Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

capturing interrupts in win32 console aplication

47 views
Skip to first unread message

anotherbrick

unread,
Oct 4, 2009, 10:16:39 AM10/4/09
to
hello ,

I am an electronics engineer from Istanbul ( Turkey )

http://www22.brinkster.com/anotherbrick/index9.htm

this is one of my products - its a paralel port PLC

I have written system software of this in real mode DOS

But I want use the big memory space of protected mode for this product
of mine
I want use one of the DPMI extenders for this

( I dont want use embedded XP or WinCE becouse I want the full control
and full speed of CPU )

But I dont know how to capture interrupts in protected mode

what I am trying to do is
to capture an hardware interrupt ( for example serial port
interrupt )
in protected mode

especially I must do this in VC++6.0 win32 console application with
help of inline assembler
after I do this I will run the application in protected mode dos

Can you show me a link in www or a way to solve this problem of my

thank you in advance

BGB / cr88192

unread,
Oct 4, 2009, 11:44:08 AM10/4/09
to

"anotherbrick" <maka...@yahoo.com> wrote in message
news:7f6c74c5-5ce8-4338...@g1g2000vbr.googlegroups.com...


in the past, there was DJGPP, which may still be around for all I know.

from what I remember (this is going back a ways), DJGPP had lots of
facilities for things of this sort.

the other option is to do it all yourself, which is basically no simple
task.
it you intend to go this route, I would recommend getting the Intel docs (if
you don't have them already), and look over how to go about all of this
(setting up PMode, using the IDT, ...).

this would likely be in "System Programming Guide, Parts 1 and 2", however,
downloading the whole thing is advised, as it contains lots of useful info.


> thank you in advance


japheth

unread,
Oct 5, 2009, 8:00:42 AM10/5/09
to
> especially I must do this in VC++6.0 win32 console application with
> help of inline assembler
> after I do this I will run the application in protected mode dos
>
> Can you show me a link in www or a way to solve this problem of my

You should try HX: http://www.japheth.de/HX.html

It's compatible with MS VC

Rod Pemberton

unread,
Oct 5, 2009, 4:15:58 PM10/5/09
to
"anotherbrick" <maka...@yahoo.com> wrote in message
news:7f6c74c5-5ce8-4338...@g1g2000vbr.googlegroups.com...
>
> I must do this in VC++6.0 win32 console application

Are you sure about using VC++6.0 for this?... IIRC, MS VC 1.52c was the
last version of VC which could produce DOS applications. A few searches on
the internet indicate VC++6.0 is not capable of producing Win32 console
applications or DOS applications, either 16-bit or 32-bit.

> after I do [win32 console] I will run the application in protected mode
dos

If it needs to work in a Win32 console, the best thing to do is code it with
Win32 in mind using a Win32 compiler that produces Win32 console
applications.

> I want use the big memory space of protected mode for this product
> of mine

Be aware that the "big memory space of protected mode", if available, will
only be available for real mode DOS. It will not be available for Win32.
What is available for real mode DOS will be limited to whatever memory size
the DPMI hosts provides. Many DPMI host limit to well below 4Gb, e.g., 2Gb,
even if 4Gb or more is available. Also, most DPMI hosts are paging, instead
of non-paging. This means that while memory is available it is not
physically mapped as one might expect. The memory is virtually mapped by
the MMU using pages. There are DPMI calls to map paged memory into physical
memory, but these calls typically will not allow you to map all memory as
physical memory. Mapping paged memory to physical memory consumes the
paging tables which are usually too small to map all memory. This can be a
problem if you are programming a physically mapped interface well above 1Mb,
with a large register file or data buffer.

> I want use one of the DPMI extenders for this
>

If your application runs in Win32, it'll use Win32's internal DPMI host, not
the one you've chosen to use with real mode DOS. E.g., you've coded your
application for DPMI 1.0 calls, then someone runs it in Win32 which doesn't
support DPMI 1.0, only DPMI 0.9. Result: problem...

Also, you'll need a DPMI hosts that works with the binaries produced by your
compiler. Typically, the application loads the DPMI host in real mode DOS.
However, some DPMI hosts can be run prior to the application and will remain
in memory (e.g., as a TSR). MS produced a DOS extender called DOSXNT. I'm
not sure for what compiler or product.

> But I dont know how to capture interrupts in protected mode
>

To capture interrupts using DPMI (instead of using Win32 methods...), you'll
need to call DPMI 0x200 Get Real Mode Interrupt Vector, and DPMI 0x201 Set
Real Mode Interrupt Vector. One you start using DPMI, the processor will be
switching between 16-bit v86 mode and 32-bit protected mode. I.e., the
hardware interrupt may occur while in either mode. So, to make sure you've
completely trapped the interrupt you may need to call DPMI 0x204 Get
Protected Mode Interrupt Vector, and DPMI 0x205 Set Protected Mode Interrupt
Vector. Typically, one sets their own interrupt routine for one cpu mode,
which will be called when an interrupt occurs in that mode. One sets a
"callback" for the interrupt in the other mode. When an interrupt occurs in
the other mode, the callback switches to the needed cpu mode, calls the new
interrupt routine, and then switches back to the original cpu mode. If
speed is an issue, you may need to code equivalent interrupts for both
modes. Your compiler may have provided named functions for the DPMI API
calls, or it may have a generic routine to call interrupts. e.g., for the
DJGPP compiler you could use __dpmi_get_protected_mode_interrupt_vector()
(among many others...), or int86() for real mode and int386() for protected
mode, etc. If not, you'll have to code your own routines.

> capturing interrupts in win32 console aplication
> especially I must do this in ... win32 console application with
> help of inline assembler

When one executes a DPMI application in a DOS-box or Win32 console, the DPMI
application uses Windows internal DPMI host, not the one you supplied for
real mode DOS. Windows internal DPMI hosts implements DPMI 0.9 API, but not
DPMI 1.0. Actually, it also implements the DPMI 1.0 math coprocessor
functions as well as all int 0x2f DPMI functions. However, you can only use
DPMI calls with true DPMI only applications. DPMI functionality and Win32
functionality are incompatible. It's unsafe to use DPMI functionality with
Win32 functionality, except for the seven Win32 safe DPMI functions. If
your application uses Win32, you can only use these seven DPMI calls safely:

0x200 Get Real Mode Interrupt Vector
0x201 Set Real Mode Interrupt Vector
0x300 Simulate Real Mode Interrupt
0x301 Call Real Mode Procedure with Far Return Frame
0x301 Call Real Mode Procedure with IRET Frame
0x303 Allocate Real Mode Callback Address
0x304 Free Real Mode Callback Address

Also, there are some limitations and problems with Win32's DPMI
implementation. I.e., that which will work in real mode DOS may not work in
Windows due to Windows restrictions. E.g., Windows restricts usage of
certain memory ranges, usually prohibits direct port and hardware access,
limits segment sizes, reduces privileges - e.g., ring 3, etc. I've had to
work through other odd and undocumented problems too. Also, win32's DPMI
host is only DPMI 0.9. So, you won't be able to use DPMI 1.0 functions.
I've found it's easier for me to develop with a non-paging DPMI host in real
mode DOS. Then, switch to a paging DPMI hosts to catch missed DPMI calls -
needed to work with paging implementations, etc. After that, I try it out
with Windows, if need be. I usually avoid DPMI 1.0 functions, not only due
to Windows, but because other DPMI hosts don't implement them completely or
properly. But, even for the DPMI 0.9 specification, many DPMI hosts don't
implement all the API calls. I.e., there is a smaller set of well defined
functions. As mentioned previously, you'll need a DPMI hosts that works
with your compiler. E.g., DJGPP can use CWSDPMI and PMODEDJ, while
OpenWatcom uses DOS4GW, Causeway and others. MS produced a DOS extender
called DOSXNT. I've not confirmed what DPMI funtionality it provides.

HTH,


Rod Pemberton


Benjamin David Lunt

unread,
Oct 5, 2009, 4:36:46 PM10/5/09
to

"Rod Pemberton" <do_no...@nohavenot.cmm> wrote in message
news:hadk8s$1fh$1...@aioe.org...

> "anotherbrick" <maka...@yahoo.com> wrote in message
> news:7f6c74c5-5ce8-4338...@g1g2000vbr.googlegroups.com...
>>
>> I must do this in VC++6.0 win32 console application
>
> Are you sure about using VC++6.0 for this?... IIRC, MS VC 1.52c was the
> last version of VC which could produce DOS applications. A few searches
> on
> the internet indicate VC++6.0 is not capable of producing Win32 console
> applications or DOS applications, either 16-bit or 32-bit.

Hi Rod,

I have used VC++ 6.0 for many years and have made many Windows
Console (DOS Box, DOS window, etc.) apps. Most of my mtools at
http://www.frontiernet.net/~fys/mtools.htm
are made with VC++ 6.0.

The VC++ 6.0 IDE anyway. I have since updated the compiler
many times, but still use the VC++ 6.0 IDE for some projects
and the VC++ 2008 IDE for most others.

The VC++ 2008 Express Edition IDE has an option to create
Win32 Console Apps too.

I am sure you know, but just for a reminder, Win Console apps
are still Windows programs. They just don't use the "windowing
interface" or whatever you'd like to call it.

I also have MS VC 1.52c, but haven't used it since the mid 1990's.

The version 6.0 IDE has its advantages, while the version 2008 IDE
has its advantages. Version 2008 really needs a more modern
processor. It can lag pretty good on something less than 2GHz
if you have anything else running in the background.

Anyway, just thought I would comment.

Ben


Maxim S. Shatskih

unread,
Oct 5, 2009, 4:57:08 PM10/5/09
to
> the internet indicate VC++6.0 is not capable of producing Win32 console
> applications or DOS applications, either 16-bit or 32-bit.

VC6 is fine capable of Win32 console apps, 32bit for sure.

--
Maxim S. Shatskih
Windows DDK MVP
ma...@storagecraft.com
http://www.storagecraft.com

BGB / cr88192

unread,
Oct 5, 2009, 6:20:21 PM10/5/09
to

"Rod Pemberton" <do_no...@nohavenot.cmm> wrote in message
news:hadk8s$1fh$1...@aioe.org...
> "anotherbrick" <maka...@yahoo.com> wrote in message
> news:7f6c74c5-5ce8-4338...@g1g2000vbr.googlegroups.com...
>>
>> I must do this in VC++6.0 win32 console application
>
> Are you sure about using VC++6.0 for this?... IIRC, MS VC 1.52c was the
> last version of VC which could produce DOS applications. A few searches
> on
> the internet indicate VC++6.0 is not capable of producing Win32 console
> applications or DOS applications, either 16-bit or 32-bit.
>

errm...

MSVC does console apps.
I use 6.1 and it does console apps just fine...

granted, unlike GCC and friends, it does not default to console apps if GUI
stuff is used, so if the app looks like a GUI app, LINK will apparently flag
it as such (thus taking away the ability to both have a GUI and a nifty
console to dump messages onto). granted, I guess one could force link via
command-line options or similar.


as for DOS, well, I don't know if it anymore has native DOS support, but it
would likely be possible to "force" it without too much additional effort
(to produce 32-bit DOS apps, probably with one supplying their own extender
and entry stub).

granted, forcing MSVC to do DOS is about the same as forcing MSVC (or, OTOH,
GCC) to produce OS kernel code. it is not strictly "fun", but one does not
have to go too far to figure out how to force it into doing so (and most of
the prerequisites would seem to, oddly, be available via command-line
options in both cases...).


>> after I do [win32 console] I will run the application in protected mode
> dos
>
> If it needs to work in a Win32 console, the best thing to do is code it
> with
> Win32 in mind using a Win32 compiler that produces Win32 console
> applications.
>

and, if it needs to work on DOS, the best thing would be to target DOS...

DJGPP is around, and I would still recommend looking into this.


>> I want use the big memory space of protected mode for this product
>> of mine
>
> Be aware that the "big memory space of protected mode", if available, will
> only be available for real mode DOS. It will not be available for Win32.
> What is available for real mode DOS will be limited to whatever memory
> size
> the DPMI hosts provides. Many DPMI host limit to well below 4Gb, e.g.,
> 2Gb,
> even if 4Gb or more is available. Also, most DPMI hosts are paging,
> instead
> of non-paging. This means that while memory is available it is not
> physically mapped as one might expect. The memory is virtually mapped by
> the MMU using pages. There are DPMI calls to map paged memory into
> physical
> memory, but these calls typically will not allow you to map all memory as
> physical memory. Mapping paged memory to physical memory consumes the
> paging tables which are usually too small to map all memory. This can be
> a
> problem if you are programming a physically mapped interface well above
> 1Mb,
> with a large register file or data buffer.
>

errm, you don't need that much space...

back when I did my own OS, for the kernel-space portion I had identity
mapped the whole 4GB memory map. note that doing so does require about 4MB
of RAM (with no PAE + 4kB pages...).

now, memory mapping may be a hassle, but it is not an issue which will kill
an effort (actually, in some ways it is actually more convinient than
physical identity mapping, since it gives a bit more flexibility as to how
one organizes their memory map, ...).

granted, the ability to remap stuff is not as compelling now, but it matters
a whole lot more when one only has a small amount of physical memory, and
wants to expand on this (for example, using 256 or 512 MB of ram, but faking
lots of processes which could easily be using this much, or even pushing the
limits of the 2-3GB the OS provides for their local process space...).


(back when I was doing kernel dev, 64MB of system RAM was fairly good, and
256MB was lots...).

(now, I am on the "other side", and have gone and written an x86
interpreter, hmm...).


>> I want use one of the DPMI extenders for this
>>
>
> If your application runs in Win32, it'll use Win32's internal DPMI host,
> not
> the one you've chosen to use with real mode DOS. E.g., you've coded your
> application for DPMI 1.0 calls, then someone runs it in Win32 which
> doesn't
> support DPMI 1.0, only DPMI 0.9. Result: problem...
>
> Also, you'll need a DPMI hosts that works with the binaries produced by
> your
> compiler. Typically, the application loads the DPMI host in real mode
> DOS.
> However, some DPMI hosts can be run prior to the application and will
> remain
> in memory (e.g., as a TSR). MS produced a DOS extender called DOSXNT.
> I'm
> not sure for what compiler or product.
>


I think the reason it comes up is because the OP wants to run the final app
in DOS.
from what I can gather, the final product would be running on an embedded
system.


<snip, lots about DPMI>


BGB / cr88192

unread,
Oct 5, 2009, 6:32:19 PM10/5/09
to

"Benjamin David Lunt" <zf...@frontiernet.net> wrote in message
news:9Rsym.27814$lR3....@newsfe25.iad...

>
> "Rod Pemberton" <do_no...@nohavenot.cmm> wrote in message
> news:hadk8s$1fh$1...@aioe.org...
>> "anotherbrick" <maka...@yahoo.com> wrote in message
>> news:7f6c74c5-5ce8-4338...@g1g2000vbr.googlegroups.com...
>>>
>>> I must do this in VC++6.0 win32 console application
>>
>> Are you sure about using VC++6.0 for this?... IIRC, MS VC 1.52c was the
>> last version of VC which could produce DOS applications. A few searches
>> on
>> the internet indicate VC++6.0 is not capable of producing Win32 console
>> applications or DOS applications, either 16-bit or 32-bit.
>
> Hi Rod,
>
> I have used VC++ 6.0 for many years and have made many Windows
> Console (DOS Box, DOS window, etc.) apps. Most of my mtools at
> http://www.frontiernet.net/~fys/mtools.htm
> are made with VC++ 6.0.
>

yep, and I may use it to compile code to work within a virtualized (AKA:
interpreted) environment... (that or I may use MinGW, not yet decided...).


I have noted that, oddly, MSVC seems to compile much faster than GCC for my
coding style, but have not fully investigated (I suspect that MSVC partly
optimizes the style for whatever reason...).

(MSVC seems to compile several source files per second, wheras GCC seems to
usually take about 1-2s per file).

so, when building, apparently most of the time actually goes into make doing
its magic...


then again, MSVC's optimizations of the produced code are hardly
impressive...


> The VC++ 6.0 IDE anyway. I have since updated the compiler
> many times, but still use the VC++ 6.0 IDE for some projects
> and the VC++ 2008 IDE for most others.
>
> The VC++ 2008 Express Edition IDE has an option to create
> Win32 Console Apps too.
>
> I am sure you know, but just for a reminder, Win Console apps
> are still Windows programs. They just don't use the "windowing
> interface" or whatever you'd like to call it.
>

yep...


actually, the main difference would seem to be the value of a single field
in the PE/COFF header, which apparently serves to determine:
if the app will be given a console when spawned;
if calls like printf will actually do anything;
...


I suspect the linker mostly tells the difference by the presence or absence
of WinMain...

WinMain==GUI


> I also have MS VC 1.52c, but haven't used it since the mid 1990's.
>
> The version 6.0 IDE has its advantages, while the version 2008 IDE
> has its advantages. Version 2008 really needs a more modern
> processor. It can lag pretty good on something less than 2GHz
> if you have anything else running in the background.
>
> Anyway, just thought I would comment.
>

I don't use the VS IDE personally...


or such...


> Ben
>
>


Maxim S. Shatskih

unread,
Oct 5, 2009, 6:46:09 PM10/5/09
to
> it as such (thus taking away the ability to both have a GUI and a nifty
> console to dump messages onto).

Not so. Write a console app (with main()) and create the windows from it.

BGB / cr88192

unread,
Oct 5, 2009, 7:02:12 PM10/5/09
to

"Maxim S. Shatskih" <ma...@storagecraft.com.no.spam> wrote in message
news:hadsvf$2ah1$1...@news.mtu.ru...

>> it as such (thus taking away the ability to both have a GUI and a nifty
>> console to dump messages onto).
>
> Not so. Write a console app (with main()) and create the windows from it.
>

with MinGW and Cygwin, one still gets a console when using 'WinMain()'...

using 'main()', one would have to go through extra effort to get the needed
handles (hInstance, ...).
but, then again, before I have noted that there are system calls for this,
so I guess this would be an option...

Maxim S. Shatskih

unread,
Oct 5, 2009, 7:10:34 PM10/5/09
to
> using 'main()', one would have to go through extra effort to get the needed
> handles (hInstance, ...).

GetStartupInfo

anotherbrick

unread,
Oct 7, 2009, 10:23:47 AM10/7/09
to

hello Japheth, thanks for answering ( to other people also many
thanks )

I have read the TSRSMPLE example in HX examples
and written a simple program which is below
this simple program must toggle Paralel port data bits
each time I touch pin 10 ( interrupt input) to ground and take away

I have compiled this below simple paralel port interrupt example with
VC++6.0 console application
I installed HX runtime in an win98 computer
I boot the DOS of win98 ( I think its dos7 )

First I run HXldr32
then I run my own exe
It loads withour error
It says " hello world" when starting and "bye bye " when finishing
but the paralel port data pins doesnot toggle when I trigger an
interrupt

the real mode version does function just the way I want : it toggles
data pins
where shall I focus ? can you give a tip ? ( also other people who can
give a tip )
---------------------------------------------0--------------------------------
#include "stdafx.h"
#include <conio.h>

unsigned long oldint0Foff;
unsigned short oldint0Fsel;
char toggle=0;

void pport_int(void);

void main(int argc, char* argv[]){

printf("Hello World!\n");

__asm{
cli

mov dx,0378h+2
mov al,010h
out dx,al

in al,021h
and al,07fh
out 021h,al

mov bl,0fh
mov ax,0204h
int 31h
mov dword ptr [oldint0Foff],edx
mov word ptr [oldint0Fsel],cx
mov ecx,0
mov cx,cs
mov edx,offset pport_int
mov ax,0205h
int 31h
sti
}

while( !_kbhit() ) ;

__asm{
cli
mov ecx,0
mov cx,word ptr [oldint0Fsel]
mov edx,dword ptr [oldint0Foff]
mov bl,0fh
mov ax,0205h
int 31h
sti
}
printf("Bye Bye!\n");


}
void pport_int(void){
toggle = !toggle;

__asm{
pusha }

if (toggle)
__asm{
mov dx,0378h
mov al,0ffh
out dx,al }

else

__asm{
mov dx,0378h
mov ax,0h
out dx,al }

__asm{
mov al,020h
out 020h,al
popa
iret }
}

japheth

unread,
Oct 7, 2009, 12:31:09 PM10/7/09
to
> First I run HXldr32
> then I run my own exe
> It loads withour error
> It says " hello world" when starting and "bye bye " when finishing
> but the paralel port data pins doesnot toggle when I trigger an
> interrupt
>
> the real mode version does function just the way I want : it toggles
> data pins
> where shall I focus ? can you give a tip ? ( also other people who can
> give a tip )

I don't know why the interrupt isn't triggered, but there are some
bugs in your interrupt routine which should be fixed first. I don't
have VC 6 anymore, so I tested it with MS VC++ Toolkit 2003:

1. the C compiler must not generate a std function prologue for your
interrupt routine. Change it to:

void __declspec(naked) pport_int(void){

2. before accessing variables inside the interrupt function, register
DS must be initialized. Also, the MSVC inline assembler wants a 32bit
version of PUSHA to save all 32bit registers.

void __declspec(naked) pport_int(void){
__asm {
push ds
pushad
mov ds,[flatds]
}
toggle = !toggle;
...

3. the inline assembler is to generate a 32bit IRET:

__ asm {
popad
pop ds
sti ;some DPMI hosts might need this!
iretd
}


4. in the initialization code, you have to init variable flatds of
course:

__asm{
cli
mov [flatds],ds


mov dx,0378h+2
mov al,010h
out dx,al

...

japheth

unread,
Oct 7, 2009, 12:39:02 PM10/7/09
to
>    __asm {
>      push ds
>      pushad
>      mov ds,[flatds]

the last line must be:

mov ds,cs:[flatds]

anotherbrick

unread,
Oct 9, 2009, 11:18:30 AM10/9/09
to

hello Japheth ,

I changed the program like you said
and success !
I see the data port pin toggle in the osciloscope

I am sending the latest version for others who interested

many thanks !

I have a question ;

have you compared any other RTOS to HX ? ( for example WinCE )
I am interested in it becouse I suppose protected mode DOS
must be faster than other RTOSs

=================================
#include "stdafx.h"
#include <conio.h>

unsigned long oldint0Foff;
unsigned short oldint0Fsel;

unsigned short flatds;
char toggle=0;


void pport_int(void);

void main(int argc, char* argv[]){

printf("Hello World!\n");

__asm{
cli

mov [flatds],ds
mov dx,0378h+2
mov al,010h
out dx,al

in al,021h
and al,07fh
out 021h,al

while( !_kbhit() ) ;


}
void __declspec (naked) pport_int(void){
__asm{
push ds
pushad
mov ds,cs:[flatds]
}

toggle = !toggle;


if (toggle)
__asm{
mov dx,0378h
mov al,0ffh
out dx,al }

else

__asm{
mov dx,0378h
mov ax,0h
out dx,al }

__asm{
mov al,020h
out 020h,al

popad
pop ds
sti
iretd }
}

japheth

unread,
Oct 10, 2009, 7:04:08 AM10/10/09
to

> have you compared any other RTOS to HX ? ( for example WinCE )
> I am interested in it becouse I suppose protected mode DOS
> must be faster than other RTOSs

No, but I once compared HDPMI (HX's DPMI host) with other hosts and
HDPMI was the fastest (and Borland's RTM.EXE the worst).

I also once tested interrupt latency of DPMI hosts when the main
program is idle in "real-mode" and the interrupt handler is a
protected-mode routine. HDPMI managed to handle up to 200k interrupts/
sec ( that is, 200k/sec switches to protected-mode and back )on a P4.
No other host was able to achieve this.


0 new messages