Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.os.msdos.programmer > #1428 > unrolled thread

XMS transfer troubles with Turbo C

Started byMateusz Viste <mateusz.viste@localhost>
First post2014-07-24 19:18 +0200
Last post2014-07-28 21:10 +0200
Articles 20 on this page of 23 — 6 participants

Back to article view | Back to comp.os.msdos.programmer


Contents

  XMS transfer troubles with Turbo C Mateusz Viste <mateusz.viste@localhost> - 2014-07-24 19:18 +0200
    Re: XMS transfer troubles with Turbo C Johann Klammer <klammerj@NOSPAM.a1.net> - 2014-07-24 22:00 +0200
      Re: XMS transfer troubles with Turbo C Mateusz Viste <mateusz.viste@localhost> - 2014-07-25 08:12 +0200
    Re: XMS transfer troubles with Turbo C Ross Ridge <rridge@csclub.uwaterloo.ca> - 2014-07-25 15:54 -0400
      Re: XMS transfer troubles with Turbo C Mateusz Viste <mateusz.viste@localhost> - 2014-07-26 16:34 +0200
        Re: XMS transfer troubles with Turbo C "Rod Pemberton" <dont_use_email@xnothavet.cqm> - 2014-07-26 13:21 -0400
          Re: XMS transfer troubles with Turbo C Mateusz Viste <mateusz.viste@localhost> - 2014-07-27 09:57 +0200
            Re: XMS transfer troubles with Turbo C Mateusz Viste <mateusz.viste@localhost> - 2014-07-27 10:38 +0200
              Re: XMS transfer troubles with Turbo C Mateusz Viste <mateusz.viste@localhost> - 2014-07-27 11:01 +0200
                Re: XMS transfer troubles with Turbo C Mateusz Viste <mateusz.viste@localhost> - 2014-07-27 11:20 +0200
                  Re: XMS transfer troubles with Turbo C Mateusz Viste <mateusz.viste@localhost> - 2014-07-27 12:07 +0200
                    Re: XMS transfer troubles with Turbo C Mateusz Viste <mateusz.viste@localhost> - 2014-07-27 12:41 +0200
                      Re: XMS transfer troubles with Turbo C Mateusz Viste <mateusz.viste@localhost> - 2014-07-27 15:46 +0200
                      Re: XMS transfer troubles with Turbo C Johann Klammer <klammerj@NOSPAM.a1.net> - 2014-07-27 16:39 +0200
                        Re: XMS transfer troubles with Turbo C Mateusz Viste <mateusz.viste@localhost> - 2014-07-27 20:09 +0200
            Re: XMS transfer troubles with Turbo C "Rod Pemberton" <dont_use_email@xnothavet.cqm> - 2014-07-27 12:32 -0400
              Re: XMS transfer troubles when AWEUTIL is loaded (exception 0D) Mateusz Viste <mateusz.viste@localhost> - 2014-07-27 20:23 +0200
        Re: XMS transfer troubles with Turbo C Ross Ridge <rridge@csclub.uwaterloo.ca> - 2014-07-27 12:25 -0400
          Re: XMS transfer troubles when AWEUTIL is loaded (exception 0D) Mateusz Viste <mateusz.viste@localhost> - 2014-07-27 20:05 +0200
            Re: XMS transfer troubles when AWEUTIL is loaded (exception 0D) "Alexei A. Frounze" <alexfrunews@gmail.com> - 2014-07-28 22:13 -0700
              Re: XMS transfer troubles when AWEUTIL is loaded (exception 0D) rugxulo@gmail.com - 2014-07-29 15:08 -0700
                Re: XMS transfer troubles when AWEUTIL is loaded (exception 0D) Mateusz Viste <mateusz.viste@localhost> - 2014-07-30 08:25 +0200
    Re: XMS transfer troubles Mateusz Viste <mateusz.viste@localhost> - 2014-07-28 21:10 +0200

Page 1 of 2  [1] 2  Next page →


#1428 — XMS transfer troubles with Turbo C

FromMateusz Viste <mateusz.viste@localhost>
Date2014-07-24 19:18 +0200
SubjectXMS transfer troubles with Turbo C
Message-ID<53d13fd3$0$2229$426a74cc@news.free.fr>

[Multipart message — attachments visible in raw view] — view raw

Hello all,

I am trying to make use of XMS memory inside a real-mode program I am 
working on. I created a very small library for XMS handling, and I am 
unable to make it work in anything else than tiny or small models... I 
use Turbo C 2.01, if it's of any importance.

I am attaching a minimalistic test program to this message (I hope it's 
okay to use attachments.. I figured that since it's smaller than many 
full-blown html mails, it would not be a problem, but if it is please 
let me know, so I wan't do it again).

The program seems to work fine in tiny and small models - ie. I am 
allocating some XMS memory, writing 16 bytes of data to it, and then 
fetching it correctly. In compact model it's unable to perform memory 
transfers, and I have no clue why.

I suspect that it's related to the fact that non-small memory models 
have more than one data segment, and that when I try to pass the address 
of my control structure to the XMS driver, it's unable to find it. From 
the XMS specification 3.0 I understood that I should pass the address of 
my structure in DS:SI, while in my code I am modifying only SI (and it's 
enough to make it work under small models). But when I try to modify the 
DS register before calling the XMS driver, I get only freezes of my 
system, or wild reboots. So I'm not sure of anything anymore.

I mirrored the XMS specification I use below:
gopher://gopher.viste-family.net/0/docs/programming/xms30.txt

I also found an old XMS library, written by Michael Graff 
(xmslbn17.zip), unfortunately it's entirely written in ASM, which I am 
not very comfortable with. The library does, however, mention some Turbo 
C specifics, and it seems to play with the BP register. I don't know 
why, since BP is never mentioned in the XMS specification... any idea? 
The extract of Michael Graff's library responsible for XMS transfers is 
this:

proc    _XMS_MoveEMB    far
         arg     MoveRec:dword

         push    bp                     ; save TurboC's bp
         mov     bp,sp                  ; use bp to address parameters
         xor     bl,bl                  ; reset error code to 0
         cmp     [_XMSInitd],0          ; has XMSSetup been called?
         jne     @@hasinitd             ; yes, continue
         mov     al,ENotInitd           ; nope, return error code
         jmp     short @@exit
@@hasinitd:
         push    ds                     ; save Turbo's data segment
         mov     ah,XMoveEMB            ; function code
         lds     si,[MoveRec]           ; Point ds:si to MoveRec
         call    [dword cs:_XMSDriver]  ; call the XMS driver
         mov     al,bl                  ; transfer XMS error code to al
         pop     ds                     ; restore Turbo's data segment
@@exit:
         pop     bp                     ; restore TurboC's bp
         ret                            ; we outa here
endp    _XMS_MoveEMB


Is anybody here fluent in this ancient XMS technology? I'd really use a 
hint or two :)


cheers,
Mateusz

[toc] | [next] | [standalone]


#1430

FromJohann Klammer <klammerj@NOSPAM.a1.net>
Date2014-07-24 22:00 +0200
Message-ID<lqroj4$76g$1@speranza.aioe.org>
In reply to#1428
On 07/24/2014 07:18 PM, Mateusz Viste wrote:
> Hello all,
>
> I am trying to make use of XMS memory inside a real-mode program I am
> working on. I created a very small library for XMS handling, and I am
> unable to make it work in anything else than tiny or small models... I
> use Turbo C 2.01, if it's of any importance.
>
> I am attaching a minimalistic test program to this message (I hope it's
> okay to use attachments.. I figured that since it's smaller than many
> full-blown html mails, it would not be a problem, but if it is please
> let me know, so I wan't do it again).
>
> The program seems to work fine in tiny and small models - ie. I am
> allocating some XMS memory, writing 16 bytes of data to it, and then
> fetching it correctly. In compact model it's unable to perform memory
> transfers, and I have no clue why.
>
> I suspect that it's related to the fact that non-small memory models
> have more than one data segment, and that when I try to pass the address
> of my control structure to the XMS driver, it's unable to find it. From
> the XMS specification 3.0 I understood that I should pass the address of
> my structure in DS:SI, while in my code I am modifying only SI (and it's
> enough to make it work under small models). But when I try to modify the
> DS register before calling the XMS driver, I get only freezes of my
> system, or wild reboots. So I'm not sure of anything anymore.
>
> I mirrored the XMS specification I use below:
> gopher://gopher.viste-family.net/0/docs/programming/xms30.txt
>
> I also found an old XMS library, written by Michael Graff
> (xmslbn17.zip), unfortunately it's entirely written in ASM, which I am
> not very comfortable with. The library does, however, mention some Turbo
> C specifics, and it seems to play with the BP register. I don't know
> why, since BP is never mentioned in the XMS specification... any idea?
> The extract of Michael Graff's library responsible for XMS transfers is
> this:
>
> proc    _XMS_MoveEMB    far
>          arg     MoveRec:dword
>
>          push    bp                     ; save TurboC's bp
>          mov     bp,sp                  ; use bp to address parameters
This is pretty standard stack frame set up(for them local vars, should 
he need any). Read the MASM docs(they're on the web) or some book on 
ASM(AoA?)... unrelated to XMS

>          xor     bl,bl                  ; reset error code to 0
>          cmp     [_XMSInitd],0          ; has XMSSetup been called?
>          jne     @@hasinitd             ; yes, continue
>          mov     al,ENotInitd           ; nope, return error code
>          jmp     short @@exit
> @@hasinitd:
>          push    ds                     ; save Turbo's data segment
>          mov     ah,XMoveEMB            ; function code
>          lds     si,[MoveRec]           ; Point ds:si to MoveRec
>          call    [dword cs:_XMSDriver]  ; call the XMS driver
>          mov     al,bl                  ; transfer XMS error code to al
>          pop     ds                     ; restore Turbo's data segment
> @@exit:
>          pop     bp                     ; restore TurboC's bp
>          ret                            ; we outa here
> endp    _XMS_MoveEMB
>
>
> Is anybody here fluent in this ancient XMS technology? I'd really use a
> hint or two :)
>
>
> cheers,
> Mateusz

AFAIR, The small models have all segs set to the same place. This does 
not mean you can omit passing DS to the XMS driver if it expects to see 
them. See if you can find some far ptr manipulation routines, cast the 
struct addr to far ptr, isolate SEG, and OFF and use it.

[toc] | [prev] | [next] | [standalone]


#1434

FromMateusz Viste <mateusz.viste@localhost>
Date2014-07-25 08:12 +0200
Message-ID<53d1f535$0$2003$426a74cc@news.free.fr>
In reply to#1430
Hi Johann,

On 07/24/2014 10:00 PM, Johann Klammer wrote:
 > AFAIR, The small models have all segs set to the same place. This
 > does not mean you can omit passing DS to the XMS driver if it expects
 > to see them. See if you can find some far ptr manipulation routines,
 > cast the struct addr to far ptr, isolate SEG, and OFF and use it.

Actually, that's exactly what I was trying, but whenever I start 
touching DS, havoc wrecks on my machine... If I don't (and use only SI), 
then the code works fine, but only in small models.

This is what I was trying:

static int xms_move(struct xms_move far *xmove) {
   unsigned int resax, resbl, oldsi, oldds;
   /* backup the SI and DS registers first */
   oldsi = _SI;
   oldds = _DS;
   /* call the xms driver */
   _AH = 0x0B;
   _DS = FP_SEG(xmove);
   _SI = FP_OFF(xmove);
   xmsdrv();
   /* save results */
   resax = _AX;
   resbl = _BL;
   /* restore old value of SI and DS */
   _DS = oldds;
   _SI = oldsi;
   /* check result */
   if (resax == 1) return(0); /* AX = 0001h if the move is successful */
   return(resbl);
}

Is there any reasong why the above would trash my system?

cheers,
Mateusz

[toc] | [prev] | [next] | [standalone]


#1450

FromRoss Ridge <rridge@csclub.uwaterloo.ca>
Date2014-07-25 15:54 -0400
Message-ID<lquclc$7j1$1@rumours.uwaterloo.ca>
In reply to#1428
Mateusz Viste  <mateusz.viste@localhost> wrote:
>I also found an old XMS library, written by Michael Graff 
>(xmslbn17.zip), unfortunately it's entirely written in ASM, which I am 
>not very comfortable with. The library does, however, mention some Turbo 
>C specifics, and it seems to play with the BP register. I don't know 
>why, since BP is never mentioned in the XMS specification... any idea? 

The comment "use bp to address parameters" gives you a hint what it's
used for. It's used to access the parameters passed to the function,
specifically the MoveRec argument declared just after the proc statement.
The instruction "lds si,[MoveRec]" will be expanded to something like
"lds si,[bp+4]".

You pretty much have no alternative than using assembly code like this
to do the transfer.  You can't reliably change _DS in C code because
it's hard to predict when the C compiler will emit code that depends on
_DS pointing to the default data segment.

You might be able to do this using inline assembly, be sure to save and
restore the DS register inside a single asm statement.

						Ross Ridge

-- 
 l/  //	  Ross Ridge -- The Great HTMU
[oo][oo]  rridge@csclub.uwaterloo.ca
-()-/()/  http://www.csclub.uwaterloo.ca/~rridge/ 
 db  //	  

[toc] | [prev] | [next] | [standalone]


#1452

FromMateusz Viste <mateusz.viste@localhost>
Date2014-07-26 16:34 +0200
Message-ID<53d3bc6c$0$2043$426a74cc@news.free.fr>
In reply to#1450
Hi Ross,

On 07/25/2014 09:54 PM, Ross Ridge wrote:
> The comment "use bp to address parameters" gives you a hint what it's
> used for. It's used to access the parameters passed to the function,
> specifically the MoveRec argument declared just after the proc statement.
> The instruction "lds si,[MoveRec]" will be expanded to something like
> "lds si,[bp+4]".

Okay, with your expansion rule I now understand that bp is used (by 
convention?) to point to the first byte of the argument list. I was a 
bit confused by the fact that bp was saved/restored, but seemingly not 
used in between. Now it's perfectly clear.
In my case I believe I don't need to care about bp at all, since I am 
using inline asm inside a C function, like this:

static unsigned int xms_memfree(void) {
   unsigned int res = 0;
   __asm {
     mov ah, 0x08
     call [dword ptr xmsdrv]  ; call the XMS driver
     mov [res], ax
   }
   return(res);
}

Am I right? (the code above works, so I think it's good)
I had to assign res a default value, otherwise the compiler was 
complaining about it being never assigned a value (which is not true, 
but I assume this is a limitation of using inline asm...).

> You pretty much have no alternative than using assembly code like this
> to do the transfer.  You can't reliably change _DS in C code because
> it's hard to predict when the C compiler will emit code that depends on
> _DS pointing to the default data segment.

That's what I did today - I removed my C operations on registers, and 
replaced them with inline ASM. So far, thing didn't changed, but I am 
not really sure what such thing mean:

         call    [dword cs:XMSDriver]

Specifically, what's the "cs:" for? XMSDriver is a DWORD that contains 
the address of an external function.
I also recompiled my program with OpenWatcom, and there, I have to use 
such construct:

         call    [dword ptr XMSDriver]

there is an additional 'ptr' that I added, because otherwise the 
compiler was complaining. By the way, is the above semantically the same 
than this one?

         call    dword ptr [XMSDriver]

I'm sorry if these questions sound lame (they most probably do). As you 
surely noticed, my knowledge of ASM is almost non-existent...

cheers,
Mateusz

[toc] | [prev] | [next] | [standalone]


#1453

From"Rod Pemberton" <dont_use_email@xnothavet.cqm>
Date2014-07-26 13:21 -0400
Message-ID<op.xjl7txpp6zenlw@localhost>
In reply to#1452
On Sat, 26 Jul 2014 10:34:20 -0400, Mateusz Viste  
<mateusz.viste@localhost> wrote:

> That's what I did today - I removed my C operations on registers, and  
> replaced them with inline ASM. So far, thing didn't changed, but I am  
> not really sure what such thing mean:
>
>          call    [dword cs:XMSDriver]
>
> Specifically, what's the "cs:" for? XMSDriver is a DWORD that contains  
> the address of an external function.

CS is a code segment override.  It tells the processor to use the code
segment register for the segment (in RM, descriptor in PM).  Normally,
the processor uses the data segment register for the segment for data,
except for a few instructions.  In 16-bit RM, this has to do with the
segment:offset addressing:

   address = segment * 16 + offset

So, if the CS segment and DS segment are both 0 then the then CS:0 and
DS:0 point to the same address.  But, if the CS segment and DS segment
are different, then their addresses would be different.

I suspect that you don't want CS here.  CS is the CS of your code,
not the CS of the XMSDriver.  You want the segment of the XMSDriver
which was returned by Int 2fh, AH=4310h.  It also takes a jump to
set CS.  You can't move a value into CS like you can with DS, ES,
FS, GS.

If you need to set the segment for the call to the XMSDriver,
you probably want to use a segment register other than CS, and
the appropriate segment register override.

You can use DS temporarily, but I'd suggest ES if it's not in use.
For 386 (or 486?) or later, you can use FS or GS (on processors where
PM is available).

Assuming you've saved the segment and offset from Int 2fh, AH=4310h
like in the XMS 3.0 specification, you'd do something like:

  mov es, [XMSDriver+2]      ; saved segment
  call [dword es:XMSDriver]

You can push and pop es, if needed.


Rod Pemberton

[toc] | [prev] | [next] | [standalone]


#1454

FromMateusz Viste <mateusz.viste@localhost>
Date2014-07-27 09:57 +0200
Message-ID<53d4b104$0$2197$426a34cc@news.free.fr>
In reply to#1453
On 07/26/2014 07:21 PM, Rod Pemberton wrote:
>> Specifically, what's the "cs:" for? XMSDriver is a DWORD that contains
>> the address of an external function.
>
> CS is a code segment override.  It tells the processor to use the code
> segment register for the segment

That's what I was thinking - but since XMSDriver is a "far" pointer 
(32bit long), isn't it supposed to already contain the right segment 
address in it's upper 16 bits?

> I suspect that you don't want CS here.  CS is the CS of your code,
> not the CS of the XMSDriver.

In fact, this CS thing isn't from me (obviously, since I don't 
understand what it's supposed to do). It's code I read in the XMS 
library by Michael Graff. In almost every function, he calls the XMS 
driver routine using this:

     call    [dword _XMSDriver]

And how the above works is pretty clear to me. But then, specifically 
for the xms "move" action (ie. the routine where one needs to play with 
SI and DS), he does it differently:

     push    ds                      ; save Turbo's data segment
     mov     ah,XMoveEMB             ; function code
     lds     si,[MoveRec]            ; Point ds:si to MoveRec
     call    [dword cs:_XMSDriver]   ; call the XMS driver
     mov     al,bl                   ; transfer XMS error code to al
     pop     ds                      ; restore Turbo's data segment

And that's the "cs:" call I was wondering about...

> You want the segment of the XMSDriver
> which was returned by Int 2fh, AH=4310h.  It also takes a jump to
> set CS.  You can't move a value into CS like you can with DS, ES,
> FS, GS.

What I am doing, is that I save the address obtained from INT 2F,AH=4310 
into an unsigned long, so it should contain the segment already, because 
the XMS spec says "The address is returned in ES:BX" (which I understand 
as "ES contains the segment, and BX hold the offset").

> Assuming you've saved the segment and offset from Int 2fh, AH=4310h
> like in the XMS 3.0 specification, you'd do something like:
>
>   mov es, [XMSDriver+2]      ; saved segment
>   call [dword es:XMSDriver]
>
> You can push and pop es, if needed.

Thanks for the suggestion - I will try it, even though I don't 
understand why such "code segment override" would be needed in the first 
place, since my XMSDriver pointer should already have the right segment 
set...

Fun fact: if I call printf() just before calling my XMS stuff, 
everything magically works. Always. I discovered this yesterday, when 
trying to trace the SEG:OFFSET address I use to call XMSdriver when it 
makes my computer freeze, and just adding a single a printf() before the 
XMS call made everything work... My two thoughts so far are that either 
printf() plays with CS in a way that pleases the XMSDriver (sounds like 
an unlikely coincidence), or printf() introduces a very slight delay 
that is long enough so a hypothetical (and unknown to me) IRQ executes 
during printf(), instead of executing during my XMS routine where I 
change DS and SI registers.

cheers,
Mateusz

[toc] | [prev] | [next] | [standalone]


#1455

FromMateusz Viste <mateusz.viste@localhost>
Date2014-07-27 10:38 +0200
Message-ID<53d4ba76$0$2120$426a74cc@news.free.fr>
In reply to#1454
On 07/27/2014 09:57 AM, Mateusz Viste wrote:
> Fun fact: if I call printf() just before calling my XMS stuff,
> everything magically works. Always.

Actually this one isn't exactly true - my "printf() fix" works only if 
the printf() call is long enough (it contains several formatting 
arguments - at least 4). I tested it again now, and it's not bullet 
proof anyway, since crashes still happens, although much less 
frequently. Weird.. looks like some timing issue.

 > Assuming you've saved the segment and offset from Int 2fh, AH=4310h
 > like in the XMS 3.0 specification, you'd do something like:
 >
 > mov es, [XMSDriver+2]      ; saved segment
 > call [dword es:XMSDriver]

I replaced my previous code:

   call dword ptr [xmsdrv]

with this:

   push es
   mov es, [word ptr xmsdrv+2]
   call dword ptr [es:xmsdrv]
   pop es

Unfortunately now my program crash immediately with "Exception 06". So 
it doesn't look to be the right way to go (note that I modified a bit 
the example your kindly provided before, because otherwise wasm was 
throwing 'invalid operands' errors at compile time).

Anyway, I'm not even sure anymore that the problem really comes from my 
XMS routines... Sure, the crash happens exactly at the time when I call 
it, but it might be a symptom of a bug elsewhere I guess. I did yet 
another test:

I kept all my XMS code as it was originally, and change something else: 
commented out all my calls to such things:

   inp(0x331);
   outp(0x330, byteval);

...and now the program runs fine (it doesn't produce anything useful, 
but all the XMS memory handling is the same).

So I'm wondering about some nasty IRQ stuff (that's what you already 
suggested a few days ago). Adding _disable() & _enable() around xms and 
port-related operation don't make it better. And I am unable to see the 
relation between XMS handling and my port requests (or IRQ firing). Why 
would one break another? Without XMS, everything works fine. Without 
port requests, everything works fine. Hell starts when I try to use 
both. I'm really glad to be a programmer today, and not 20 years ago. :)

Mateusz

[toc] | [prev] | [next] | [standalone]


#1456

FromMateusz Viste <mateusz.viste@localhost>
Date2014-07-27 11:01 +0200
Message-ID<53d4bfd7$0$1975$426a74cc@news.free.fr>
In reply to#1455
Okay, a little additional test:

- I placed a 2ms sleep right before calling my XMS routine (and after 
doing my port operations): everything works.
- I replaced the 2ms sleep with a 1ms sleep: the program crashes again

So this would confirm some sort of timing (IRQ?) issue. And at least it 
explains why adding a "printf()" was inhibiting the problem.

I'm not sure if I defined what "crash" means yet - what happens is 
exactly this:

  JemmEx: exception 0D occured at CS:EIP=0008:00110F78,
  ERRC=00000000 SS:ESP=0010:F8004FA0 EBP=F8004FB4 EFL=00013046
  CR0=80000011 CR2=00000000 EAX=00000B3C EBX=00484814
  ECX=00000002 EDX=00000EE3 ESI=00480F3C EDI=00480000

Before, I was using HIMEM + UMBPCI, and there the behavior was 
different: Instead of getting an onscreen message with the exception, I 
was experiencing a wild reboot (I switched to Jemmex then, because I 
figured that the behavior in virtual 86 would be more 'controlled').

Mateusz



On 07/27/2014 10:38 AM, Mateusz Viste wrote:
> On 07/27/2014 09:57 AM, Mateusz Viste wrote:
>> Fun fact: if I call printf() just before calling my XMS stuff,
>> everything magically works. Always.
>
> Actually this one isn't exactly true - my "printf() fix" works only if
> the printf() call is long enough (it contains several formatting
> arguments - at least 4). I tested it again now, and it's not bullet
> proof anyway, since crashes still happens, although much less
> frequently. Weird.. looks like some timing issue.
>
>  > Assuming you've saved the segment and offset from Int 2fh, AH=4310h
>  > like in the XMS 3.0 specification, you'd do something like:
>  >
>  > mov es, [XMSDriver+2]      ; saved segment
>  > call [dword es:XMSDriver]
>
> I replaced my previous code:
>
>    call dword ptr [xmsdrv]
>
> with this:
>
>    push es
>    mov es, [word ptr xmsdrv+2]
>    call dword ptr [es:xmsdrv]
>    pop es
>
> Unfortunately now my program crash immediately with "Exception 06". So
> it doesn't look to be the right way to go (note that I modified a bit
> the example your kindly provided before, because otherwise wasm was
> throwing 'invalid operands' errors at compile time).
>
> Anyway, I'm not even sure anymore that the problem really comes from my
> XMS routines... Sure, the crash happens exactly at the time when I call
> it, but it might be a symptom of a bug elsewhere I guess. I did yet
> another test:
>
> I kept all my XMS code as it was originally, and change something else:
> commented out all my calls to such things:
>
>    inp(0x331);
>    outp(0x330, byteval);
>
> ...and now the program runs fine (it doesn't produce anything useful,
> but all the XMS memory handling is the same).
>
> So I'm wondering about some nasty IRQ stuff (that's what you already
> suggested a few days ago). Adding _disable() & _enable() around xms and
> port-related operation don't make it better. And I am unable to see the
> relation between XMS handling and my port requests (or IRQ firing). Why
> would one break another? Without XMS, everything works fine. Without
> port requests, everything works fine. Hell starts when I try to use
> both. I'm really glad to be a programmer today, and not 20 years ago. :)
>
> Mateusz

[toc] | [prev] | [next] | [standalone]


#1457

FromMateusz Viste <mateusz.viste@localhost>
Date2014-07-27 11:20 +0200
Message-ID<53d4c441$0$2908$426a74cc@news.free.fr>
In reply to#1456
Yet another "interesting" observation:

Sometimes, when the 0D exception occurs in my program, and I reboot the 
computer (by pressing the "RESET" switch connected to the mainboard), 
during boot time my sound card's driver (AWEUTIL) triggers an exception 
0D, too. This doesn't happen every time that my program crashes, but 
let's say 1 time for 10 reboots.

What I find odd is that I thought that a reset was, well - resetting all 
computer's states. But it obviously appears that after I induce an 
exception, something, somewhere, stays dormant, and is triggered again 
by the AWEUTIL driver of my soundcard during the boot that follows.

The exception triggered by AWEUTIL is very similar to the one I get with 
my program (compare it with the one I posted a few moments ago - same 
CS:EIP, same SS:ESP...):

   JemmEx: exception 0D occured at CS:EIP=0008:00110F78,
   ERRC=00000000 SS:ESP=0010:F8004FA4 EBP=F8004FB4 EFL=00013046
   CR0=80000011 CR2=00000000 EAX=00008EBF EBX=00000172
   ECX=00000002 EDX=00000331 ESI=00000100 EDI=0000FFFE

Note, that AWEUTIL do NOT trigger any exception on "normal" reboots. It 
happens only on (some) reboots that follow a crash in my program.

Isn't this disturbing?

Mateusz



On 07/27/2014 11:01 AM, Mateusz Viste wrote:
> Okay, a little additional test:
>
> - I placed a 2ms sleep right before calling my XMS routine (and after
> doing my port operations): everything works.
> - I replaced the 2ms sleep with a 1ms sleep: the program crashes again
>
> So this would confirm some sort of timing (IRQ?) issue. And at least it
> explains why adding a "printf()" was inhibiting the problem.
>
> I'm not sure if I defined what "crash" means yet - what happens is
> exactly this:
>
>   JemmEx: exception 0D occured at CS:EIP=0008:00110F78,
>   ERRC=00000000 SS:ESP=0010:F8004FA0 EBP=F8004FB4 EFL=00013046
>   CR0=80000011 CR2=00000000 EAX=00000B3C EBX=00484814
>   ECX=00000002 EDX=00000EE3 ESI=00480F3C EDI=00480000
>
> Before, I was using HIMEM + UMBPCI, and there the behavior was
> different: Instead of getting an onscreen message with the exception, I
> was experiencing a wild reboot (I switched to Jemmex then, because I
> figured that the behavior in virtual 86 would be more 'controlled').
>
> Mateusz
>
>
>
> On 07/27/2014 10:38 AM, Mateusz Viste wrote:
>> On 07/27/2014 09:57 AM, Mateusz Viste wrote:
>>> Fun fact: if I call printf() just before calling my XMS stuff,
>>> everything magically works. Always.
>>
>> Actually this one isn't exactly true - my "printf() fix" works only if
>> the printf() call is long enough (it contains several formatting
>> arguments - at least 4). I tested it again now, and it's not bullet
>> proof anyway, since crashes still happens, although much less
>> frequently. Weird.. looks like some timing issue.
>>
>>  > Assuming you've saved the segment and offset from Int 2fh, AH=4310h
>>  > like in the XMS 3.0 specification, you'd do something like:
>>  >
>>  > mov es, [XMSDriver+2]      ; saved segment
>>  > call [dword es:XMSDriver]
>>
>> I replaced my previous code:
>>
>>    call dword ptr [xmsdrv]
>>
>> with this:
>>
>>    push es
>>    mov es, [word ptr xmsdrv+2]
>>    call dword ptr [es:xmsdrv]
>>    pop es
>>
>> Unfortunately now my program crash immediately with "Exception 06". So
>> it doesn't look to be the right way to go (note that I modified a bit
>> the example your kindly provided before, because otherwise wasm was
>> throwing 'invalid operands' errors at compile time).
>>
>> Anyway, I'm not even sure anymore that the problem really comes from my
>> XMS routines... Sure, the crash happens exactly at the time when I call
>> it, but it might be a symptom of a bug elsewhere I guess. I did yet
>> another test:
>>
>> I kept all my XMS code as it was originally, and change something else:
>> commented out all my calls to such things:
>>
>>    inp(0x331);
>>    outp(0x330, byteval);
>>
>> ...and now the program runs fine (it doesn't produce anything useful,
>> but all the XMS memory handling is the same).
>>
>> So I'm wondering about some nasty IRQ stuff (that's what you already
>> suggested a few days ago). Adding _disable() & _enable() around xms and
>> port-related operation don't make it better. And I am unable to see the
>> relation between XMS handling and my port requests (or IRQ firing). Why
>> would one break another? Without XMS, everything works fine. Without
>> port requests, everything works fine. Hell starts when I try to use
>> both. I'm really glad to be a programmer today, and not 20 years ago. :)
>>
>> Mateusz
>

[toc] | [prev] | [next] | [standalone]


#1458

FromMateusz Viste <mateusz.viste@localhost>
Date2014-07-27 12:07 +0200
Message-ID<53d4cf5f$0$2032$426a34cc@news.free.fr>
In reply to#1457
Now, reading the "AWE32" article on Wikipedia, I see this:

"To support older software, the AWE32 (...) came with the AWEUTIL 
program which attempted to provide GM/MT-32/GS redirection to the native 
AWE hardware; however, AWEUTIL wasn't compatible with all programs or 
motherboards due to its use of the non-maskable interrupt"

I don't know exactly how this translates to the low-level tech stuff, 
but might be that this is related to all my exception 0D troubles... (my 
hardware is a SB64 AWE, but from what I've read it's nearly identical to 
the AWE32 at the software level).

Mateusz




On 07/27/2014 11:20 AM, Mateusz Viste wrote:
> Yet another "interesting" observation:
>
> Sometimes, when the 0D exception occurs in my program, and I reboot the
> computer (by pressing the "RESET" switch connected to the mainboard),
> during boot time my sound card's driver (AWEUTIL) triggers an exception
> 0D, too. This doesn't happen every time that my program crashes, but
> let's say 1 time for 10 reboots.
>
> What I find odd is that I thought that a reset was, well - resetting all
> computer's states. But it obviously appears that after I induce an
> exception, something, somewhere, stays dormant, and is triggered again
> by the AWEUTIL driver of my soundcard during the boot that follows.
>
> The exception triggered by AWEUTIL is very similar to the one I get with
> my program (compare it with the one I posted a few moments ago - same
> CS:EIP, same SS:ESP...):
>
>    JemmEx: exception 0D occured at CS:EIP=0008:00110F78,
>    ERRC=00000000 SS:ESP=0010:F8004FA4 EBP=F8004FB4 EFL=00013046
>    CR0=80000011 CR2=00000000 EAX=00008EBF EBX=00000172
>    ECX=00000002 EDX=00000331 ESI=00000100 EDI=0000FFFE
>
> Note, that AWEUTIL do NOT trigger any exception on "normal" reboots. It
> happens only on (some) reboots that follow a crash in my program.
>
> Isn't this disturbing?
>
> Mateusz
>
>
>
> On 07/27/2014 11:01 AM, Mateusz Viste wrote:
>> Okay, a little additional test:
>>
>> - I placed a 2ms sleep right before calling my XMS routine (and after
>> doing my port operations): everything works.
>> - I replaced the 2ms sleep with a 1ms sleep: the program crashes again
>>
>> So this would confirm some sort of timing (IRQ?) issue. And at least it
>> explains why adding a "printf()" was inhibiting the problem.
>>
>> I'm not sure if I defined what "crash" means yet - what happens is
>> exactly this:
>>
>>   JemmEx: exception 0D occured at CS:EIP=0008:00110F78,
>>   ERRC=00000000 SS:ESP=0010:F8004FA0 EBP=F8004FB4 EFL=00013046
>>   CR0=80000011 CR2=00000000 EAX=00000B3C EBX=00484814
>>   ECX=00000002 EDX=00000EE3 ESI=00480F3C EDI=00480000
>>
>> Before, I was using HIMEM + UMBPCI, and there the behavior was
>> different: Instead of getting an onscreen message with the exception, I
>> was experiencing a wild reboot (I switched to Jemmex then, because I
>> figured that the behavior in virtual 86 would be more 'controlled').
>>
>> Mateusz
>>
>>
>>
>> On 07/27/2014 10:38 AM, Mateusz Viste wrote:
>>> On 07/27/2014 09:57 AM, Mateusz Viste wrote:
>>>> Fun fact: if I call printf() just before calling my XMS stuff,
>>>> everything magically works. Always.
>>>
>>> Actually this one isn't exactly true - my "printf() fix" works only if
>>> the printf() call is long enough (it contains several formatting
>>> arguments - at least 4). I tested it again now, and it's not bullet
>>> proof anyway, since crashes still happens, although much less
>>> frequently. Weird.. looks like some timing issue.
>>>
>>>  > Assuming you've saved the segment and offset from Int 2fh, AH=4310h
>>>  > like in the XMS 3.0 specification, you'd do something like:
>>>  >
>>>  > mov es, [XMSDriver+2]      ; saved segment
>>>  > call [dword es:XMSDriver]
>>>
>>> I replaced my previous code:
>>>
>>>    call dword ptr [xmsdrv]
>>>
>>> with this:
>>>
>>>    push es
>>>    mov es, [word ptr xmsdrv+2]
>>>    call dword ptr [es:xmsdrv]
>>>    pop es
>>>
>>> Unfortunately now my program crash immediately with "Exception 06". So
>>> it doesn't look to be the right way to go (note that I modified a bit
>>> the example your kindly provided before, because otherwise wasm was
>>> throwing 'invalid operands' errors at compile time).
>>>
>>> Anyway, I'm not even sure anymore that the problem really comes from my
>>> XMS routines... Sure, the crash happens exactly at the time when I call
>>> it, but it might be a symptom of a bug elsewhere I guess. I did yet
>>> another test:
>>>
>>> I kept all my XMS code as it was originally, and change something else:
>>> commented out all my calls to such things:
>>>
>>>    inp(0x331);
>>>    outp(0x330, byteval);
>>>
>>> ...and now the program runs fine (it doesn't produce anything useful,
>>> but all the XMS memory handling is the same).
>>>
>>> So I'm wondering about some nasty IRQ stuff (that's what you already
>>> suggested a few days ago). Adding _disable() & _enable() around xms and
>>> port-related operation don't make it better. And I am unable to see the
>>> relation between XMS handling and my port requests (or IRQ firing). Why
>>> would one break another? Without XMS, everything works fine. Without
>>> port requests, everything works fine. Hell starts when I try to use
>>> both. I'm really glad to be a programmer today, and not 20 years ago. :)
>>>
>>> Mateusz
>>
>

[toc] | [prev] | [next] | [standalone]


#1459

FromMateusz Viste <mateusz.viste@localhost>
Date2014-07-27 12:41 +0200
Message-ID<53d4d774$0$2910$426a34cc@news.free.fr>
In reply to#1458
Hello guys, still spamming you here. :)

After learning about the "AWEUTIL" SoundBlaster driver doing some kinky 
NMI interactions, I removed it from my autoexec.bat. I was thinking - 
normally everything should be working the same way, with the exception 
that now I won't have MIDI sound.

Without the AWEUTIL driver, my program behaves *very* differently: it 
instantly freezes the computer, and something displays a single message 
on screen: "Parity Check 2  0000".

I tested a few different XMS memory managers, and this happens with all 
of them: JemmEx, Himemx and XMGR (the message is exactly the same, so 
it's likely to come from something else than the XMS manager...).

Since a few days I'm wondering if my hardware could be broken... But it 
does work fine with anything else (DOS games, midi players, 
compilers...), and does weird things only whith my own program, so I'd 
rather still say that my program is buggy, although the symptoms are 
really odd. Also, I did check the memory using the MEMTEST tool from 
Alexander Grigoriev, and it detected no anomaly.

Anyway, I'm starting wondering about getting some other hardware (other 
mainboard, and/or other MPU-401 card), so I could see if I have the same 
troubles..

Mateusz




On 07/27/2014 12:07 PM, Mateusz Viste wrote:
> Now, reading the "AWE32" article on Wikipedia, I see this:
>
> "To support older software, the AWE32 (...) came with the AWEUTIL
> program which attempted to provide GM/MT-32/GS redirection to the native
> AWE hardware; however, AWEUTIL wasn't compatible with all programs or
> motherboards due to its use of the non-maskable interrupt"
>
> I don't know exactly how this translates to the low-level tech stuff,
> but might be that this is related to all my exception 0D troubles... (my
> hardware is a SB64 AWE, but from what I've read it's nearly identical to
> the AWE32 at the software level).
>
> Mateusz
>
>
>
>
> On 07/27/2014 11:20 AM, Mateusz Viste wrote:
>> Yet another "interesting" observation:
>>
>> Sometimes, when the 0D exception occurs in my program, and I reboot the
>> computer (by pressing the "RESET" switch connected to the mainboard),
>> during boot time my sound card's driver (AWEUTIL) triggers an exception
>> 0D, too. This doesn't happen every time that my program crashes, but
>> let's say 1 time for 10 reboots.
>>
>> What I find odd is that I thought that a reset was, well - resetting all
>> computer's states. But it obviously appears that after I induce an
>> exception, something, somewhere, stays dormant, and is triggered again
>> by the AWEUTIL driver of my soundcard during the boot that follows.
>>
>> The exception triggered by AWEUTIL is very similar to the one I get with
>> my program (compare it with the one I posted a few moments ago - same
>> CS:EIP, same SS:ESP...):
>>
>>    JemmEx: exception 0D occured at CS:EIP=0008:00110F78,
>>    ERRC=00000000 SS:ESP=0010:F8004FA4 EBP=F8004FB4 EFL=00013046
>>    CR0=80000011 CR2=00000000 EAX=00008EBF EBX=00000172
>>    ECX=00000002 EDX=00000331 ESI=00000100 EDI=0000FFFE
>>
>> Note, that AWEUTIL do NOT trigger any exception on "normal" reboots. It
>> happens only on (some) reboots that follow a crash in my program.
>>
>> Isn't this disturbing?
>>
>> Mateusz
>>
>>
>>
>> On 07/27/2014 11:01 AM, Mateusz Viste wrote:
>>> Okay, a little additional test:
>>>
>>> - I placed a 2ms sleep right before calling my XMS routine (and after
>>> doing my port operations): everything works.
>>> - I replaced the 2ms sleep with a 1ms sleep: the program crashes again
>>>
>>> So this would confirm some sort of timing (IRQ?) issue. And at least it
>>> explains why adding a "printf()" was inhibiting the problem.
>>>
>>> I'm not sure if I defined what "crash" means yet - what happens is
>>> exactly this:
>>>
>>>   JemmEx: exception 0D occured at CS:EIP=0008:00110F78,
>>>   ERRC=00000000 SS:ESP=0010:F8004FA0 EBP=F8004FB4 EFL=00013046
>>>   CR0=80000011 CR2=00000000 EAX=00000B3C EBX=00484814
>>>   ECX=00000002 EDX=00000EE3 ESI=00480F3C EDI=00480000
>>>
>>> Before, I was using HIMEM + UMBPCI, and there the behavior was
>>> different: Instead of getting an onscreen message with the exception, I
>>> was experiencing a wild reboot (I switched to Jemmex then, because I
>>> figured that the behavior in virtual 86 would be more 'controlled').
>>>
>>> Mateusz
>>>
>>>
>>>
>>> On 07/27/2014 10:38 AM, Mateusz Viste wrote:
>>>> On 07/27/2014 09:57 AM, Mateusz Viste wrote:
>>>>> Fun fact: if I call printf() just before calling my XMS stuff,
>>>>> everything magically works. Always.
>>>>
>>>> Actually this one isn't exactly true - my "printf() fix" works only if
>>>> the printf() call is long enough (it contains several formatting
>>>> arguments - at least 4). I tested it again now, and it's not bullet
>>>> proof anyway, since crashes still happens, although much less
>>>> frequently. Weird.. looks like some timing issue.
>>>>
>>>>  > Assuming you've saved the segment and offset from Int 2fh, AH=4310h
>>>>  > like in the XMS 3.0 specification, you'd do something like:
>>>>  >
>>>>  > mov es, [XMSDriver+2]      ; saved segment
>>>>  > call [dword es:XMSDriver]
>>>>
>>>> I replaced my previous code:
>>>>
>>>>    call dword ptr [xmsdrv]
>>>>
>>>> with this:
>>>>
>>>>    push es
>>>>    mov es, [word ptr xmsdrv+2]
>>>>    call dword ptr [es:xmsdrv]
>>>>    pop es
>>>>
>>>> Unfortunately now my program crash immediately with "Exception 06". So
>>>> it doesn't look to be the right way to go (note that I modified a bit
>>>> the example your kindly provided before, because otherwise wasm was
>>>> throwing 'invalid operands' errors at compile time).
>>>>
>>>> Anyway, I'm not even sure anymore that the problem really comes from my
>>>> XMS routines... Sure, the crash happens exactly at the time when I call
>>>> it, but it might be a symptom of a bug elsewhere I guess. I did yet
>>>> another test:
>>>>
>>>> I kept all my XMS code as it was originally, and change something else:
>>>> commented out all my calls to such things:
>>>>
>>>>    inp(0x331);
>>>>    outp(0x330, byteval);
>>>>
>>>> ...and now the program runs fine (it doesn't produce anything useful,
>>>> but all the XMS memory handling is the same).
>>>>
>>>> So I'm wondering about some nasty IRQ stuff (that's what you already
>>>> suggested a few days ago). Adding _disable() & _enable() around xms and
>>>> port-related operation don't make it better. And I am unable to see the
>>>> relation between XMS handling and my port requests (or IRQ firing). Why
>>>> would one break another? Without XMS, everything works fine. Without
>>>> port requests, everything works fine. Hell starts when I try to use
>>>> both. I'm really glad to be a programmer today, and not 20 years
>>>> ago. :)
>>>>
>>>> Mateusz
>>>
>>
>

[toc] | [prev] | [next] | [standalone]


#1460

FromMateusz Viste <mateusz.viste@localhost>
Date2014-07-27 15:46 +0200
Message-ID<53d502b7$0$2122$426a74cc@news.free.fr>
In reply to#1459
Please ignore my last message - the "Parity Check" troubles occuring 
when running my program without AWEUTIL are only occurring when I reset 
my computer after an exception error, so I guess it must remain in some 
shitty state. Since now on, I always do a "power off/wait 10s/power on" 
cycle between each of my tests.

So now, when booting in a "clean" state:

Without AWEUTIL: My program WORKS. I mean, "works as expected, without 
crashing, and without requiring any artificial voodoo delays". Of course 
writing to port 0x330 doesn't produce any sound without AWEUTIL's MIDI 
emulation. Everything is simply redirected onto the MIDI out port of my 
sound card, instead of being played with the card's synth. But I 
connected my MIDI keyboard to it, and it does work very well.

With AWEUTIL: It still crashes, as I wrote in previous messages, with 
the "Exception 0D" message.

So all in all, I start firmly believing that AWEUTIL does some 
uncatholic things (which wikipedia already suggests in the AWE32 article 
I mentioned before), and that it somehow clashes with my XMS routines. 
How to find a workaround is beyond my imagination, but it must be 
possible - many DOS games and midi players work fine on this computer 
with AWEUTIL.

Mateusz



On 07/27/2014 12:41 PM, Mateusz Viste wrote:
> Hello guys, still spamming you here. :)
>
> After learning about the "AWEUTIL" SoundBlaster driver doing some kinky
> NMI interactions, I removed it from my autoexec.bat. I was thinking -
> normally everything should be working the same way, with the exception
> that now I won't have MIDI sound.
>
> Without the AWEUTIL driver, my program behaves *very* differently: it
> instantly freezes the computer, and something displays a single message
> on screen: "Parity Check 2  0000".
>
> I tested a few different XMS memory managers, and this happens with all
> of them: JemmEx, Himemx and XMGR (the message is exactly the same, so
> it's likely to come from something else than the XMS manager...).
>
> Since a few days I'm wondering if my hardware could be broken... But it
> does work fine with anything else (DOS games, midi players,
> compilers...), and does weird things only whith my own program, so I'd
> rather still say that my program is buggy, although the symptoms are
> really odd. Also, I did check the memory using the MEMTEST tool from
> Alexander Grigoriev, and it detected no anomaly.
>
> Anyway, I'm starting wondering about getting some other hardware (other
> mainboard, and/or other MPU-401 card), so I could see if I have the same
> troubles..
>
> Mateusz
>
>
>
>
> On 07/27/2014 12:07 PM, Mateusz Viste wrote:
>> Now, reading the "AWE32" article on Wikipedia, I see this:
>>
>> "To support older software, the AWE32 (...) came with the AWEUTIL
>> program which attempted to provide GM/MT-32/GS redirection to the native
>> AWE hardware; however, AWEUTIL wasn't compatible with all programs or
>> motherboards due to its use of the non-maskable interrupt"
>>
>> I don't know exactly how this translates to the low-level tech stuff,
>> but might be that this is related to all my exception 0D troubles... (my
>> hardware is a SB64 AWE, but from what I've read it's nearly identical to
>> the AWE32 at the software level).
>>
>> Mateusz
>>
>>
>>
>>
>> On 07/27/2014 11:20 AM, Mateusz Viste wrote:
>>> Yet another "interesting" observation:
>>>
>>> Sometimes, when the 0D exception occurs in my program, and I reboot the
>>> computer (by pressing the "RESET" switch connected to the mainboard),
>>> during boot time my sound card's driver (AWEUTIL) triggers an exception
>>> 0D, too. This doesn't happen every time that my program crashes, but
>>> let's say 1 time for 10 reboots.
>>>
>>> What I find odd is that I thought that a reset was, well - resetting all
>>> computer's states. But it obviously appears that after I induce an
>>> exception, something, somewhere, stays dormant, and is triggered again
>>> by the AWEUTIL driver of my soundcard during the boot that follows.
>>>
>>> The exception triggered by AWEUTIL is very similar to the one I get with
>>> my program (compare it with the one I posted a few moments ago - same
>>> CS:EIP, same SS:ESP...):
>>>
>>>    JemmEx: exception 0D occured at CS:EIP=0008:00110F78,
>>>    ERRC=00000000 SS:ESP=0010:F8004FA4 EBP=F8004FB4 EFL=00013046
>>>    CR0=80000011 CR2=00000000 EAX=00008EBF EBX=00000172
>>>    ECX=00000002 EDX=00000331 ESI=00000100 EDI=0000FFFE
>>>
>>> Note, that AWEUTIL do NOT trigger any exception on "normal" reboots. It
>>> happens only on (some) reboots that follow a crash in my program.
>>>
>>> Isn't this disturbing?
>>>
>>> Mateusz
>>>
>>>
>>>
>>> On 07/27/2014 11:01 AM, Mateusz Viste wrote:
>>>> Okay, a little additional test:
>>>>
>>>> - I placed a 2ms sleep right before calling my XMS routine (and after
>>>> doing my port operations): everything works.
>>>> - I replaced the 2ms sleep with a 1ms sleep: the program crashes again
>>>>
>>>> So this would confirm some sort of timing (IRQ?) issue. And at least it
>>>> explains why adding a "printf()" was inhibiting the problem.
>>>>
>>>> I'm not sure if I defined what "crash" means yet - what happens is
>>>> exactly this:
>>>>
>>>>   JemmEx: exception 0D occured at CS:EIP=0008:00110F78,
>>>>   ERRC=00000000 SS:ESP=0010:F8004FA0 EBP=F8004FB4 EFL=00013046
>>>>   CR0=80000011 CR2=00000000 EAX=00000B3C EBX=00484814
>>>>   ECX=00000002 EDX=00000EE3 ESI=00480F3C EDI=00480000
>>>>
>>>> Before, I was using HIMEM + UMBPCI, and there the behavior was
>>>> different: Instead of getting an onscreen message with the exception, I
>>>> was experiencing a wild reboot (I switched to Jemmex then, because I
>>>> figured that the behavior in virtual 86 would be more 'controlled').
>>>>
>>>> Mateusz
>>>>
>>>>
>>>>
>>>> On 07/27/2014 10:38 AM, Mateusz Viste wrote:
>>>>> On 07/27/2014 09:57 AM, Mateusz Viste wrote:
>>>>>> Fun fact: if I call printf() just before calling my XMS stuff,
>>>>>> everything magically works. Always.
>>>>>
>>>>> Actually this one isn't exactly true - my "printf() fix" works only if
>>>>> the printf() call is long enough (it contains several formatting
>>>>> arguments - at least 4). I tested it again now, and it's not bullet
>>>>> proof anyway, since crashes still happens, although much less
>>>>> frequently. Weird.. looks like some timing issue.
>>>>>
>>>>>  > Assuming you've saved the segment and offset from Int 2fh, AH=4310h
>>>>>  > like in the XMS 3.0 specification, you'd do something like:
>>>>>  >
>>>>>  > mov es, [XMSDriver+2]      ; saved segment
>>>>>  > call [dword es:XMSDriver]
>>>>>
>>>>> I replaced my previous code:
>>>>>
>>>>>    call dword ptr [xmsdrv]
>>>>>
>>>>> with this:
>>>>>
>>>>>    push es
>>>>>    mov es, [word ptr xmsdrv+2]
>>>>>    call dword ptr [es:xmsdrv]
>>>>>    pop es
>>>>>
>>>>> Unfortunately now my program crash immediately with "Exception 06". So
>>>>> it doesn't look to be the right way to go (note that I modified a bit
>>>>> the example your kindly provided before, because otherwise wasm was
>>>>> throwing 'invalid operands' errors at compile time).
>>>>>
>>>>> Anyway, I'm not even sure anymore that the problem really comes
>>>>> from my
>>>>> XMS routines... Sure, the crash happens exactly at the time when I
>>>>> call
>>>>> it, but it might be a symptom of a bug elsewhere I guess. I did yet
>>>>> another test:
>>>>>
>>>>> I kept all my XMS code as it was originally, and change something
>>>>> else:
>>>>> commented out all my calls to such things:
>>>>>
>>>>>    inp(0x331);
>>>>>    outp(0x330, byteval);
>>>>>
>>>>> ...and now the program runs fine (it doesn't produce anything useful,
>>>>> but all the XMS memory handling is the same).
>>>>>
>>>>> So I'm wondering about some nasty IRQ stuff (that's what you already
>>>>> suggested a few days ago). Adding _disable() & _enable() around xms
>>>>> and
>>>>> port-related operation don't make it better. And I am unable to see
>>>>> the
>>>>> relation between XMS handling and my port requests (or IRQ firing).
>>>>> Why
>>>>> would one break another? Without XMS, everything works fine. Without
>>>>> port requests, everything works fine. Hell starts when I try to use
>>>>> both. I'm really glad to be a programmer today, and not 20 years
>>>>> ago. :)
>>>>>
>>>>> Mateusz
>>>>
>>>
>>
>

[toc] | [prev] | [next] | [standalone]


#1461

FromJohann Klammer <klammerj@NOSPAM.a1.net>
Date2014-07-27 16:39 +0200
Message-ID<lr32sr$2ff$1@speranza.aioe.org>
In reply to#1459
On 07/27/2014 12:41 PM, Mateusz Viste wrote:
> Hello guys, still spamming you here. :)
>
> After learning about the "AWEUTIL" SoundBlaster driver doing some kinky
> NMI interactions, I removed it from my autoexec.bat. I was thinking -
> normally everything should be working the same way, with the exception
> that now I won't have MIDI sound.
>
> Without the AWEUTIL driver, my program behaves *very* differently: it
> instantly freezes the computer, and something displays a single message
> on screen: "Parity Check 2  0000".
>
[snip]
Check for that parity boot virus... I remember messages like that...
Did you run some program you got from a 'friend'?
If it's not that, it is possible your bios is broken or PSU failing...
...
And remove those old quotes. It's getting painful to read.

[toc] | [prev] | [next] | [standalone]


#1469

FromMateusz Viste <mateusz.viste@localhost>
Date2014-07-27 20:09 +0200
Message-ID<53d54075$0$2024$426a74cc@news.free.fr>
In reply to#1461
On 07/27/2014 04:39 PM, Johann Klammer wrote:
> Check for that parity boot virus... I remember messages like that...
> Did you run some program you got from a 'friend'?
> If it's not that, it is possible your bios is broken or PSU failing...

Yeah, I also noticed doing a web search that these "parity check" 
message could be issued by a virus form the nineties. This is not 
impossible, since I do have LOTS of DOS stuff on my PC, coming from 
different places. And if there's one thing I don't have, it's an antivirus.

But the "parity check" virus seem to be a diskette boot sector virus 
that makes the system freeze every hour. That's not my case. And other 
software works fine, the only problem I have is with my own program.

Nevertheless, I will try to find a DOS antivirus and perform a scan - 
it's always a good thing to do. :)

Mateusz

[toc] | [prev] | [next] | [standalone]


#1464

From"Rod Pemberton" <dont_use_email@xnothavet.cqm>
Date2014-07-27 12:32 -0400
Message-ID<op.xjnz8rde6zenlw@localhost>
In reply to#1454
On Sun, 27 Jul 2014 03:57:57 -0400, Mateusz Viste  
<mateusz.viste@localhost> wrote:

> On 07/26/2014 07:21 PM, Rod Pemberton wrote:
>>> Specifically, what's the "cs:" for? XMSDriver is a DWORD that contains
>>> the address of an external function.
>>
>> CS is a code segment override.  It tells the processor to use the code
>> segment register for the segment
>
> That's what I was thinking - but since XMSDriver is a "far" pointer  
> (32bit long), isn't it supposed to already contain the right segment  
> address in it's upper 16 bits?
>

x86 has multiple forms of the call instruction.  One will pick up the
segment and offset from memory.  They other will just use the offset.
Usually, you just need a "far" keyword to the form which uses both.
So, instead of setting up the CS as I suggested, you probably just
need a far keyword.

>> I suspect that you don't want CS here.  CS is the CS of your code,
>> not the CS of the XMSDriver.
>
> In fact, this CS thing isn't from me (obviously, since I don't  
> understand what it's supposed to do). It's code I read in the XMS  
> library by Michael Graff. In almost every function, he calls the XMS  
> driver routine using this:
>
>      call    [dword _XMSDriver]
>

I would think he'd need a "far" keyword here.  Otherwise, the assembler
is like to use the offset only form.  E.g., somesuch:

       call far  [dword _XMSDriver]
       call    [far dword _XMSDriver]

> And how the above works is pretty clear to me. But then, specifically  
> for the xms "move" action (ie. the routine where one needs to play with  
> SI and DS), he does it differently:
>
>      push    ds                      ; save Turbo's data segment
>      mov     ah,XMoveEMB             ; function code
>      lds     si,[MoveRec]            ; Point ds:si to MoveRec
>      call    [dword cs:_XMSDriver]   ; call the XMS driver
>      mov     al,bl                   ; transfer XMS error code to al
>      pop     ds                      ; restore Turbo's data segment
>
> And that's the "cs:" call I was wondering about...

This implies that _XMSDriver routine is within his code segment.
That's unlikely, unless _XMSDriver routine is a routine of his
and not the actual call to the XMS driver.  That might be why
he doesn't need a "far" keyword above too.

>> Assuming you've saved the segment and offset from Int 2fh, AH=4310h
>> like in the XMS 3.0 specification, you'd do something like:
>>
>>   mov es, [XMSDriver+2]      ; saved segment
>>   call [dword es:XMSDriver]
>>
>> You can push and pop es, if needed.
>
> Thanks for the suggestion - I will try it, even though I don't
> understand why such "code segment override" would be needed in the first
> place, since my XMSDriver pointer should already have the right segment
> set...

It's the difference between a "near" and "far" call in x86.
x86 supports a call to just an offset.  In that case, the CS
segment is used as the segment for the address.  x86 also
supports a far call.  This loads both the segment and offset.

Your address will need to match whatever form you're using
for assembly or C.

The C compiler may use a different format of it's own too.
E.g., for 16-bit RM C, typically, the MK_FP() macro or
function is used to construct an address, whereas in 32-bit
PM C code, the compiler will usually just use the offset since
offsets are larger, 32-bits.  This means you can assign
addresses directly to a pointer in 32-bit code.  Sometimes you
have to add an offset to adjust where the pointer points.
Othertimes, you don't.  This is C compiler specific stuff.

> Fun fact: if I call printf() just before calling my XMS stuff,  
> everything magically works. Always.

That's usually an indication of a memory leak or out-of-bounds
reference of some sort.  printf() routines allocate memory.
When they do, your code works.

> I discovered this yesterday, when trying to trace the SEG:OFFSET address  
> I use to call XMSdriver when it makes my computer freeze, and just  
> adding a single a printf() before the XMS call made everything work...  
> My two thoughts so far are that either printf() plays with CS in a way  
> that pleases the XMSDriver (sounds like an unlikely coincidence), or  
> printf() introduces a very slight delay that is long enough so a  
> hypothetical (and unknown to me) IRQ executes during printf(), instead  
> of executing during my XMS routine where I change DS and SI registers.

It could be something other than a memory leak.  I'm not familiar with
Turbo C.  But, that's been the case with DJGPP (GCC for DOS).

I read your other messages, but have nothing to add.


Rod Pemberton

[toc] | [prev] | [next] | [standalone]


#1473 — Re: XMS transfer troubles when AWEUTIL is loaded (exception 0D)

FromMateusz Viste <mateusz.viste@localhost>
Date2014-07-27 20:23 +0200
SubjectRe: XMS transfer troubles when AWEUTIL is loaded (exception 0D)
Message-ID<53d543b7$0$1997$426a74cc@news.free.fr>
In reply to#1464
On 07/27/2014 06:32 PM, Rod Pemberton wrote:
> x86 has multiple forms of the call instruction.  One will pick up the
> segment and offset from memory.  They other will just use the offset.
> Usually, you just need a "far" keyword to the form which uses both.
> So, instead of setting up the CS as I suggested, you probably just
> need a far keyword.

Okay, I understand now. In fact, I had a "far" keyword from the 
beginning - so my code worked fine without any overriding :)

> That's usually an indication of a memory leak or out-of-bounds
> reference of some sort.  printf() routines allocate memory.
> When they do, your code works.

Yes, I know printf() does different things on its own - but in this 
specific case it seem to be a timing problem/clash against AWEUTIL (the 
MIDI emulator driver shipped with my SB64 AWE card).

As I wrote in one of my latest messages, simply waiting 2ms between 
outputting to the port 0x330 (where AWEUTIL awaits) and using my XMS 
routines makes the whole program work (no more exceptions).

cheers,
Mateusz

[toc] | [prev] | [next] | [standalone]


#1465

FromRoss Ridge <rridge@csclub.uwaterloo.ca>
Date2014-07-27 12:25 -0400
Message-ID<lr395q$hhe$1@rumours.uwaterloo.ca>
In reply to#1452
Mateusz Viste  <mateusz.viste@localhost> wrote:
>That's what I did today - I removed my C operations on registers, and 
>replaced them with inline ASM. So far, thing didn't changed, but I am 
>not really sure what such thing mean:
>
>         call    [dword cs:XMSDriver]

Ah, yes, sorry, I should have caught that.  You know how I said you can't
safely change _DS because you can't be sure what code the compiler will
generate that will be dependent on the DS registers?  Well, you have to
be careful that when you change the value of the DS segment register in
assembly that none of your instructions after that implictly depend on
the old value of DS.

So why use the CS overide (the "cs:" part of the instuction), why not
just do this:

	call	[dword XMSDriver]

Well this instruction implicitly uses the DS register. It's the equivilent
of this instruction which makes the use of DS explicit.

	call	[dword ds:XMSDriver]

This instruction loads the DWORD at the address calculated by taking
the offset of the address where XMSDriver is located and adding to the
value of the DS segment.  The segment part of the address of XMSDriver
is doesn't form part of this caclulation.  That DWORD value is then
interpretted as a far pointer which is used to load CS and IP.

When you use a CS override instead of a DS override, it does the same
thing except that it adds the value of the CS segment to the offset
of XMSDriver.

Why does the assembly code do this? Well, hopefully it's obvious, it
does this because it changed the value of DS.  If XMSDriver was located
in the segment that DS normally points to then, it would no longer be
accessible through DS.  So the assembly code either assumes that CS =
DS, or the that the XMSDriver variable was defined in the code segment
rather than data segment.

You need to solve this problem the same way. Either find a segment
register that already happens to have the same value, or put your
equivilent of the XMSDriver variable in the code segment.  Since you're
probably not using the tiny memory model you can't assume CS = DS,
but you're probably using a memory model were SS = DS.  So using a SS
override ("ss:") should work.  

Alternatively you can put your XMSDriver variable in the code segment.
I believe this is how you would do it in Turbo C, but I can't easily
test it:

	void far * _cs XMSDriver;

>I also recompiled my program with OpenWatcom, and there, I have to use 
>such construct:
>
>         call    [dword ptr XMSDriver]
>
>there is an additional 'ptr' that I added, because otherwise the 
>compiler was complaining. By the way, is the above semantically the same 
>than this one?
>
>         call    dword ptr [XMSDriver]

They're probably equivilent but depends on the assembler and I'm not
familiar with the Watcom assembler.  I think TASM might treat them
differently in Ideal mode.

Note that you shouldn't actually need the use DWORD PTR cast with
OpenWatcom, the compiler and/or assembler should know the type and size
of XMSDriver and so pick the correct instruction. You need to the use the
"dword" operand size override with NASM because it doesn't use types,
and so doesn't know the size of XMSDriver, even if it was defined earlier
in the same assembly file.  It's default assumption if you don't use
"dword" is that XMSDriver is word sized, and so generates a near call
instead of far call.

					Ross Ridge

-- 
 l/  //	  Ross Ridge -- The Great HTMU
[oo][oo]  rridge@csclub.uwaterloo.ca
-()-/()/  http://www.csclub.uwaterloo.ca/~rridge/ 
 db  //	  

[toc] | [prev] | [next] | [standalone]


#1468 — Re: XMS transfer troubles when AWEUTIL is loaded (exception 0D)

FromMateusz Viste <mateusz.viste@localhost>
Date2014-07-27 20:05 +0200
SubjectRe: XMS transfer troubles when AWEUTIL is loaded (exception 0D)
Message-ID<53d53f54$0$2024$426a74cc@news.free.fr>
In reply to#1465
Hi Ross!

On 07/27/2014 06:25 PM, Ross Ridge wrote:
> So why use the CS overide (the "cs:" part of the instuction), why not
> just do this:
>
> 	call	[dword XMSDriver]
>
> Well this instruction implicitly uses the DS register. It's the equivilent
> of this instruction which makes the use of DS explicit.
>
> 	call	[dword ds:XMSDriver]

Now I understand, thanks! I was focusing on the "value" of the 
XMSDriver, while the cs: magic was about getting to the variable itself.

So the XMS library I was looking at was most probably written with tiny 
model in mind.

In my case, I wasn't overriding the XMSDriver variable after playing 
with DS, and it worked anyway, so I can only assume that wasm is smart 
enough to figure this out.

I did however change my code to this:

unsigned int tmpseg, resax;
unsigned char bl;
__asm {
   push bp            ; save BP (just in case)
   push ds            ; save DS
   push si            ; save SI
   push es            ; save ES
   mov ah, 0x0b       ; xms function is 0x0b ("move block")
   mov tmpseg, ds     ; save DS into ES via a tmp variable. I need
   mov es, tmpseg     ; old DS so I can access my xmsdrv variable.
   lds si, [xmove]    ;
   call dword ptr [es:xmsdrv] ; call the XMS driver
   pop es             ; restore original ES
   pop si             ; restore original SI
   pop ds             ; restore original DS
   pop bp             ; restore original BP
   mov resax, ax      ; save exit status
   mov resbl, bl      ; save result
}

I used a temporary 'tmpseg' word here, simply because I couldn't make a 
direct "mov es, ds" (watcom asm is not allowing this and complains about 
'invalid operands').

Anyway, the changed code works exactly as before - ie works very well 
unless AWEUTIL MIDI emulation is loaded, at which point the program 
works for a few seconds and crashes with a 0D exception.

Thank you for the extensive explanations - even if it doesn't solve my 
primary problem (which I start to believe is not related to the XMS code 
at all, but to some weird interactions with AWEUTIL), I did learn a lot. 
Head hurts now, but coder happy :) Thanks!

Mateusz

[toc] | [prev] | [next] | [standalone]


#1488 — Re: XMS transfer troubles when AWEUTIL is loaded (exception 0D)

From"Alexei A. Frounze" <alexfrunews@gmail.com>
Date2014-07-28 22:13 -0700
SubjectRe: XMS transfer troubles when AWEUTIL is loaded (exception 0D)
Message-ID<f40889a3-2b01-4a33-aa86-545cfc419b0e@googlegroups.com>
In reply to#1468
On Sunday, July 27, 2014 11:05:08 AM UTC-7, Mateusz Viste wrote:

<snip>

> I used a temporary 'tmpseg' word here, simply because I couldn't make a 
> direct "mov es, ds" (watcom asm is not allowing this and complains about 
> 'invalid operands').

It's not "watcom asm". There simply isn't an x86 instruction to move a value from a segment register into another segment register. Look up your favorite x86 instruction set reference.

Alex

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.os.msdos.programmer


csiph-web