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

[Hook out HW interrupt IRQ14 with Watcom C+DOS/32a in DOS ]

556 views
Skip to first unread message

liaoo

unread,
Jul 25, 2012, 11:50:53 AM7/25/12
to
Dear all,
I have a question about how to hook out HW interrupt in "flat memory" model..Maybe you can give me some directions...

@ about my application...
- created by combining Watcom C and DOS32/A. Memory model is "flat"
- written for running on DOS mode only...
- now I can access >1M memory and allocate large memory with dos extender...

@ current issue...
- I want to test the ISR(interrupt service routine) for one PCI card. Thus I need to "hook" out the HW interrupt IRQ 14 to test...
- the PCI card's interrupt line(0x3C) = 0xE in DOS mode. That means this device will issue interrupt via 8259's IRQ 14.

But... I did not how to achieve my goal to hook out this interrupt in "flat mode" ?

@ what I have tried:
1. in watcom C's lib document, there is one sample code using _dos_getvect, _dos_setvect, and _chain_intr to hook INT 0x1C...I tested this code and found OK. If applying to INT 8 or 9 still OK !

But if applying this to INT 76h( here 76h means: interrupt number for IRQ14 and is from: (14-8)+0x70h for PIC mode... ) I found my code is not invoked !


* I have checked HW interrupt is generated correctly but... my own ISR did NOT invoked...

2. I have tried using DPMI function 0x204/0x205 to get/set Protected Mode interrupt vector. But still in vain...(my own ISR is still not called...!)

Do I miss something ? Is there anyone doing this before ? or could you provide me some directions ?

Any help will be appreciated...! Thanks !

cg_chas

unread,
Jul 25, 2012, 10:41:08 PM7/25/12
to
On Wed, 25 Jul 2012 08:50:53 -0700 (PDT), liaoo <jimmy...@gmail.com> wrote:

>Dear all,
>I have a question about how to hook out HW interrupt in "flat memory" model..Maybe you can give me some directions...
>
>@ about my application...
>- created by combining Watcom C and DOS32/A. Memory model is "flat"
>- written for running on DOS mode only...
>- now I can access >1M memory and allocate large memory with dos extender...
>
>@ current issue...
>- I want to test the ISR(interrupt service routine) for one PCI card. Thus I need to "hook" out the HW interrupt IRQ 14 to test...
>- the PCI card's interrupt line(0x3C) = 0xE in DOS mode. That means this device will issue interrupt via 8259's IRQ 14.
>
>But... I did not how to achieve my goal to hook out this interrupt in "flat mode" ?
>
>@ what I have tried:
>1. in watcom C's lib document, there is one sample code using _dos_getvect, _dos_setvect, and _chain_intr to hook INT 0x1C...I tested this code and found OK. If applying to INT 8 or 9 still OK !
>
>But if applying this to INT 76h( here 76h means: interrupt number for IRQ14 and is from: (14-8)+0x70h for PIC mode... ) I found my code is not invoked !
>
>
>* I have checked HW interrupt is generated correctly but... my own ISR did NOT invoked...

How exactly did you perform this check?

>
>2. I have tried using DPMI function 0x204/0x205 to get/set Protected Mode interrupt vector. But still in vain...(my own ISR is still not called...!)
>
>Do I miss something ? Is there anyone doing this before ? or could you provide me some directions ?
>
>Any help will be appreciated...! Thanks !

With regards to DOS mode (real mode DOS) and IRQ14, 76h _is_ the correct
interrupt vector.

Assuming you are sending the proper instructions to the PIC and have a proper
ISR, which it seems that you do given your success with other interrupts,
could it be possible that IRQ14 is not the correct line for your handler for
your PCI?

Could your BIOS be remapping PCI devices to other IRQ lines?

Charles

cg_chas

unread,
Jul 25, 2012, 10:51:58 PM7/25/12
to
On Wed, 25 Jul 2012 08:50:53 -0700 (PDT), liaoo <jimmy...@gmail.com> wrote:

This also may be applicable.

http://www.openwatcom.org/index.php/PCI_Interrupt_Routing

Charles

liaoo

unread,
Jul 25, 2012, 11:06:50 PM7/25/12
to
> How exactly did you perform this check?
=> The way I checked if HW actually generates interrupt is: to see the interrupt status bit in that PCI device configuration space offset 06h bit3(IS). I found it was 1!(...but my own ISR is not invoked >_<...)

> Could your BIOS be remapping PCI devices to other IRQ lines?
1. Someone told me to re-configure the IRQ resource allocation and let my PCI device use the IRQx within [0~7]. I modified it in BIOS setup menu and now PCI device used IRQ3 ... Then retest again and found own ISR is still not invoked...(BUT again if applying the same code for IRQ0 and IRQ1 own ISR is called correctly...
=> that is, IRQ0/1 ok but... IRQ3 failed... why ?

2. I did not know how to identify if BIOS remaps and I only know in DOS mode system should be in PIC mode(2x 8259)....

I am just wondering about why IRQ1/2 ok BUT IRQ3 failed ....

cg_chas

unread,
Jul 26, 2012, 12:06:34 AM7/26/12
to
On Wed, 25 Jul 2012 20:06:50 -0700 (PDT), liaoo <jimmy...@gmail.com> wrote:

>> How exactly did you perform this check?
>=> The way I checked if HW actually generates interrupt is: to see the interrupt status bit in that PCI device configuration space offset 06h bit3(IS). I found it was 1!(...but my own ISR is not invoked >_<...)
Is there also an interrupt disable bit to check? (in the command register)
0 means the INTx# signal will be asserted, otherwise the INTx# signal will be
ignored.

>
>> Could your BIOS be remapping PCI devices to other IRQ lines?
>1. Someone told me to re-configure the IRQ resource allocation and let my PCI device use the IRQx within [0~7]. I modified it in BIOS setup menu and now PCI device used IRQ3 ... Then retest again and found own ISR is still not invoked...(BUT again if applying the same code for IRQ0 and IRQ1 own ISR is called correctly...
>=> that is, IRQ0/1 ok but... IRQ3 failed... why ?
>
>2. I did not know how to identify if BIOS remaps and I only know in DOS mode system should be in PIC mode(2x 8259)....
The easiest way to identify the remapping I was referring to would be to look
and see if your BIOS setup menu has a way options for configuring PCI
interrupt signals such as INTA# INTB# INTC# INTD#.

Sometimes this is not configurable by any means other than physically
selecting the slot for the PCI card.

I do not think all motherboards route PCI interrupts to the 8259 by default.
Although I think most _can_ be set up to do so.

>
>I am just wondering about why IRQ1/2 ok BUT IRQ3 failed ....
Perhaps it is something with the routing of your motherboard's PCI interrupt
requests to the PIC which is handled by the chipset.

Which motherboard are you using?

liaoo

unread,
Jul 26, 2012, 12:42:19 AM7/26/12
to
> Is there also an interrupt disable bit to check? (in the command register)
> 0 means the INTx# signal will be asserted, otherwise the INTx# signal will be
> ignored.
=> Yes, there is one bit in command register bit10 for interrupt disable. I have checked it before and it was 0...!

> The easiest way to identify the remapping I was referring to would be to look
> and see if your BIOS setup menu has a way options for configuring PCI
> interrupt signals such as INTA# INTB# INTC# INTD#.
=> The BIOS is AMI BIOS and I only found "IRQ Resource Setup" and within it I can see IRQ3/4/5/7/9/10/11/14/15 and I can choose [Available] or [Reserved] for each IRQ... I did not see anything about INT #A/#B ...(maybe they are not opened for user access...)

> I do not think all motherboards route PCI interrupts to the 8259 by default.
> Although I think most _can_ be set up to do so.
=> Maybe I have to check this first...>_<...

> Which motherboard are you using?
=> I used MSI g33m motherboard and it was intel chipset ...!

thanks !

cg_chas

unread,
Jul 26, 2012, 9:07:54 AM7/26/12
to
On Wed, 25 Jul 2012 21:42:19 -0700 (PDT), liaoo <jimmy...@gmail.com> wrote:

>> Is there also an interrupt disable bit to check? (in the command register)
>> 0 means the INTx# signal will be asserted, otherwise the INTx# signal will be
>> ignored.
>=> Yes, there is one bit in command register bit10 for interrupt disable. I have checked it before and it was 0...!
>
>> The easiest way to identify the remapping I was referring to would be to look
>> and see if your BIOS setup menu has a way options for configuring PCI
>> interrupt signals such as INTA# INTB# INTC# INTD#.
>=> The BIOS is AMI BIOS and I only found "IRQ Resource Setup" and within it I can see IRQ3/4/5/7/9/10/11/14/15 and I can choose [Available] or [Reserved] for each IRQ... I did not see anything about INT #A/#B ...(maybe they are not opened for user access...)

This type of setting, [Available] or [Reserved] is generally for limiting
certain IRQ lines for use by the BIOS plug and play resource allocator.

When an IRQ is [Reserved], it will be usable only by non plug and play devices
such as legacy non plug and play ISA.

When an IRQ is [Available], the plug and play BIOS will include the available
IRQ as a resource that _might_ be automatically assigned to a device.

[Available] does not guarantee the assignment of a given IRQ. Where
[Reserved] does guarantee _non assignment_.

>
>> I do not think all motherboards route PCI interrupts to the 8259 by default.
>> Although I think most _can_ be set up to do so.
>=> Maybe I have to check this first...>_<...

I would be curious what settings if any, your BIOS menu has for configuring or
disabling the I/O APIC.

I would also be curious if ACPI is enabled by default in your BIOS menu.

I would also be curious if your PCI configuration space has Message Signaled
Interrupts enabled by default for default PCI intialization.

Each of these settings would indicate modern interrupt handling and might
explain why you are not seeing PCI interrupts at the standard PIC.

>
>> Which motherboard are you using?
>=> I used MSI g33m motherboard and it was intel chipset ...!

This is a relatively new motherboard where PCI is concerned.
It is PCI v2.3 and it has an I/O APIC as well as is ACPI 2.0 compliant.

I/O APIC is not the same as a single or cascaded 8259 PIC. An I/O APIC
contains a redirection table which is used to route interrupts as well as a
whole architecture of additional functionality that supercedes the limited
8259. I/O APICs are common to SMP processors such as the Core 2 that your
motherboard supports. I/O APICs have functionality that is tied to SMP
processors.

Assuming your motherboard did not have an I/O APIC and just had 8259s, to use
the standard PIC with PCI I would expect that you would just have to
configure:

Interrupt Disable
Interrupt Line (very important)
Interrupt Pin (may or may not be configurable)

If it did not work I would experiment with various settings for all of the
above 3 registers as there may be some mutual exclusivity between them.

Since your motherboard _does_ have an I/O APIC, you must see what has to be
done to disable it, otherwise, I am guessing you will not be able to use the
standard PIC(s) the way you want to.

>
>thanks !

I wish I could be of more help.
Charles

JJ

unread,
Jul 26, 2012, 10:05:37 AM7/26/12
to
liaoo <jimmy...@gmail.com> wrote:

> - I want to test the ISR(interrupt service routine) for one PCI
> card. Thus I need to "hook" out the HW interrupt IRQ 14 to
> test... - the PCI card's interrupt line(0x3C) = 0xE in DOS mode.
> That means this device will issue interrupt via 8259's IRQ 14.

You should use other IRQ. IRQ 14-15 are used for IDE controllers. IRQ
14 is for primary, and IRQ 15 is for secondary. Both are not
shareable unless each device is disabled in BIOS. Same goes to other
non-disableable device IRQs such as system timer and keyboard.

liaoo

unread,
Jul 26, 2012, 10:41:43 AM7/26/12
to
> You should use other IRQ. IRQ 14-15 are used for IDE controllers. IRQ
> 14 is for primary, and IRQ 15 is for secondary. Both are not
> shareable unless each device is disabled in BIOS. Same goes to other
> non-disableable device IRQs such as system timer and keyboard.
=> Thanks for your suggestion first...

The PCI device I want to test is actually an AHCI controller. After choosing AHCI mode enabled in BIOS setup menu, I found IRQ14 is assigned to AHCI controller. Besides my motherboard incorporates one IDE card/controller but I did not check its IRQ...

All I want to say is: I reserved IRQ14 in BIOS setup menu then found AHCI controller was assigned to IRQ3(ori: IRQ14), but still failed in this case...!

liaoo

unread,
Jul 26, 2012, 11:10:12 AM7/26/12
to
> This type of setting, [Available] or [Reserved] is generally for limiting
> certain IRQ lines for use by the BIOS plug and play resource allocator.
>
> When an IRQ is [Reserved], it will be usable only by non plug and play devices
> such as legacy non plug and play ISA.
>
> When an IRQ is [Available], the plug and play BIOS will include the available
> IRQ as a resource that _might_ be automatically assigned to a device.
>
> [Available] does not guarantee the assignment of a given IRQ. Where
> [Reserved] does guarantee _non assignment_.
=> yes, you are right ! I tried to reserve IRQ14 then found PCI device is assigned to IRQ3. The reason why I doing so is some people said maybe DOS/32A just takes care of IRQ0~IRQ7... BUT in this situation my own ISR is still not invoked...

> I would be curious what settings if any, your BIOS menu has for configuring or
> disabling the I/O APIC.
>
> I would also be curious if ACPI is enabled by default in your BIOS menu.
>
> I would also be curious if your PCI configuration space has Message Signaled
> Interrupts enabled by default for default PCI intialization.
>
> Each of these settings would indicate modern interrupt handling and might
> explain why you are not seeing PCI interrupts at the standard PIC.
=> There is one option in setup menu to enable/disable IO APIC, but I did not know exactly what this option means. Maybe I should figure it out...

Besides I checked the MSI capability of that PCI device and found MSIE = 0,thus the interrupt is not "MSI", it should be pin-based interrupt.

As for ACPI enabled, I remembered ACPI mode is enabled for OS only and did not know its influence on DOS mode. Maybe I should figure it out also...

> This is a relatively new motherboard where PCI is concerned.
> It is PCI v2.3 and it has an I/O APIC as well as is ACPI 2.0 compliant.
>
> I/O APIC is not the same as a single or cascaded 8259 PIC. An I/O APIC
> contains a redirection table which is used to route interrupts as well as a
> whole architecture of additional functionality that supercedes the limited
> 8259. I/O APICs are common to SMP processors such as the Core 2 that your
> motherboard supports. I/O APICs have functionality that is tied to SMP
> processors.
>
> Assuming your motherboard did not have an I/O APIC and just had 8259s, to use
> the standard PIC with PCI I would expect that you would just have to
> configure:
>
> Interrupt Disable
> Interrupt Line (very important)
> Interrupt Pin (may or may not be configurable)
>
> If it did not work I would experiment with various settings for all of the
> above 3 registers as there may be some mutual exclusivity between them.
>
> Since your motherboard _does_ have an I/O APIC, you must see what has to be
> done to disable it, otherwise, I am guessing you will not be able to use the
> standard PIC(s) the way you want to.
=> I will disable IO APIC and/or ACPI first then try again...

But I am still wondering why the same code for IRQ0/1 ok, BUT for IRQ3 it failed...? The only difference I know between IRQ1/2 and IRQ3 is the interrupt initiator...The former is not PCI device BUT the latter is...

I would be curious maybe this is the limitation of DOS/32A or APIs...

I have to thank you because you provided lots of valuable information/suggestions...Please inform me if you have other suggestions... !

Thanks again...!

Rod Pemberton

unread,
Jul 27, 2012, 4:13:22 PM7/27/12
to
"liaoo" <jimmy...@gmail.com> wrote in message
news:82fd41a6-ff0c-4077...@googlegroups.com...
...

> - created by combining Watcom C and DOS32/A. Memory model is "flat"
> - written for running on DOS mode only...
> - now I can access >1M memory and allocate large memory with dos
> extender...
>

The mention of DOS32/A suggests this is a DPMI application. Are you
compiling for 16-bit RM DOS as "wcl/l=dos" or for 32-bit DOS PM DPMI
as "wcl386/l=dos4g" ?

The reason I ask is because 32-bit DPMI applications call PM interrupts in
the DPMI's IDT table. This means there are *two* interrupt tables when
using DPMI applications: the BIOS's RM IVT and the DPMI host's PM IDT. The
DPMI host won't call RM interrupts in the BIOS' IVT table. You have to set
up that code yourself using DPMI calls. This can cause missed interrupts if
setup incorrectly or not setup. That might be what you're experiencing.
I.e., a specific interrupt may be called, but is calling the wrong interrupt
routine in the wrong cpu mode. E.g., you're triggering RM interrupt, but
the PM interrupt is being called. Or, the opposite is occuring.

Either way, you'll have to setup at least one interrupt in one of them
(either the PM IDT or RM IVT). You may also need to setup an interrupt in
the other. Or, you may need to install a callback from the interrupt in one
mode to call the interrupt in the other mode.

There are DPMI calls which will setup both RM IVT or PM IDT vectors, and
callbacks so an IVT can call and IDT, or an IDT can call an IVT. For DPMI
calls with OpenWatcom, you'll have to use int386x() and RMI struct since
OpenWatcom doesn't have function wrappers for DPMI calls, unlike the DJGPP
compiler.

See basic use of int386x() here:
http://www.openwatcom.org/index.php/Accessing_the_Harddisk_using_LBA_under_DPMI

> 1. in watcom C's lib document, there is one sample code using
> _dos_getvect, _dos_setvect, and _chain_intr to hook INT 0x1C...
>

That's for a RM IVT. You might need a PM IDT interrupt routine since you're
using DOS32/A. It depends on your code.


Rod Pemberton





Rod Pemberton

unread,
Jul 27, 2012, 4:13:59 PM7/27/12
to
"cg_chas" <cg_...@hotmail.com> wrote in message
news:c1c2189dt85g18udo...@4ax.com...
> On Wed, 25 Jul 2012 21:42:19 -0700 (PDT), liaoo <jimmy...@gmail.com>
wrote:

> Since your motherboard _does_ have an I/O APIC, you must see what has to
> be done to disable it, otherwise, I am guessing you will not be able to
> use the standard PIC(s) the way you want to.

He can use the 8259's until I/O APIC is enabled. I use them on machines
with I/O APICs without ever using the I/O APICs. The 8259's are either
present as hardware or emulated via BIOS or somesuch...

In an OS project of mine, I use the standard BIOS IRQ setup for my PICs.
0x08 for PIC1 and 0x70 for PIC2. Although, I do set them via ICW2
just to make sure they are the values I expect.

Most people say you need to remap the PICs since they are shared between
interrupts and IRQ's. That's not actually true. You can determine what
triggered a specific interrupt afterwards. It just takes more work:

In an interrupt, you can check the instruction stream (IP saved on stack) to
see if the last instruction was an INT instruction (0xCD). If so, the
interrupt is a software interrupt, or it could be a fault. You can then
check to see if the software interrupt number called matches the interrupt
number you're in. If not, it's a fault, instead of a software interrupt.
If the interrupt number is a possible IRQ interrupt, you can read the low or
high PIC's ISR register to see if it was an IRQ. If so, the interrupt is an
IRQ. The routine I use to separate these is more complicated than that, but
that's the basic outline.


Rod Pemberton







liaoo

unread,
Jul 28, 2012, 1:57:01 AM7/28/12
to
> The mention of DOS32/A suggests this is a DPMI application. Are you
>
> compiling for 16-bit RM DOS as "wcl/l=dos" or for 32-bit DOS PM DPMI
>
> as "wcl386/l=dos4g" ?
=> I have some questions about above statement and please point out the mistakes for corrections because I am the newbie on DOS extender...

First after checking "all" my makefiles I found keyword "dos4g" is NOT used. The content of my "main" make file is as follows(part):
---------------------------------------------------
INCLUDE1 = -i=c:\source\util -i=c:\watcom\h
OBJECTS1 = util.obj
CFLAGS = -zq -fp6 -mf -s -oxsbl $(INCLUDE1)
DEST = util.exe
COMPILER = wpp386
LINKER = wlink
LNK_FILE = util.lnk

.erase # special cmd, tell wmake to "erase" target if make is not successful

.cpp.obj: .AUTODEPEND
$(COMPILER) $(CFLAGS) $<

$(DEST) : $(OBJECTS1) makefile util.lnk
$(LINKER) @$(LNK_FILE)
---------------------------------------------------

And other make files are just like below:
---------------------------------------------------
INCLUDE1 = -ic:\watcom\h
OBJECTS1 = actitem.obj
CFLAGS = -zq -mf -oxsbl $(INCLUDE1)
DEST = action.exe
COMPILER = wpp386

.erase # special cmd, tell wmake to "erase" target if make is not successful

.cpp.obj: .AUTODEPEND
$(COMPILER) $(CFLAGS) $<

$(DEST) : $(OBJECTS1) makefile
---------------------------------------------------

Thus I will say I found no "dos4g" in my makefile...! Could I ask why "wcl386/l=dos4g" is required if installing PM handler ? Without "wcl386/l=dos4g" my app can access >1M memory and allocate much more memory than before ! And my app surely runs at flat memory mode...

Second I want to know why using "dos4g" instead of "dos32a" ? (I am using DOS/32a and not dos4g or dos4gw...)

* There is "dos32a.exe" in my lnk file like below:
---------------------------------------------------
FILE biosutil.obj
option osname='32-bit protected mode DOS'
format os2 le
option stack=65535
libpath %WATCOM%\lib386
libpath %WATCOM%\lib386\dos

library pci\pci.lib
library ide\ide.lib
library action\action.lib
library errors\error.lib
library operatio\operatio.lib

# The "STUB" option specifies an executable file containing
# a "stub" program that is to be placed at the "beginning" of
# the executable file being

op stub=dos32a.exe
---------------------------------------------------

Do I lose something ?

>
>
>
> The reason I ask is because 32-bit DPMI applications call PM interrupts in
>
> the DPMI's IDT table. This means there are *two* interrupt tables when
>
> using DPMI applications: the BIOS's RM IVT and the DPMI host's PM IDT. The
>
> DPMI host won't call RM interrupts in the BIOS' IVT table. You have to set
>
> up that code yourself using DPMI calls. This can cause missed interrupts if
>
> setup incorrectly or not setup. That might be what you're experiencing.
>
> I.e., a specific interrupt may be called, but is calling the wrong interrupt
>
> routine in the wrong cpu mode. E.g., you're triggering RM interrupt, but
>
> the PM interrupt is being called. Or, the opposite is occuring.
>
>
>
> Either way, you'll have to setup at least one interrupt in one of them
>
> (either the PM IDT or RM IVT). You may also need to setup an interrupt in
>
> the other. Or, you may need to install a callback from the interrupt in one
>
> mode to call the interrupt in the other mode.
=> Does above mean: I have to setup both the PM and RM handlers, that is, bimodal interrupt support ?

> There are DPMI calls which will setup both RM IVT or PM IDT vectors, and
>
> callbacks so an IVT can call and IDT, or an IDT can call an IVT. For DPMI
>
> calls with OpenWatcom, you'll have to use int386x() and RMI struct since
>
> OpenWatcom doesn't have function wrappers for DPMI calls, unlike the DJGPP
>
> compiler.
=> I did not use the int386x() but I used assembly language by #pragma aux ... to implement DPMI calls(int 31h)

> That's for a RM IVT. You might need a PM IDT interrupt routine since you're
>
> using DOS32/A. It depends on your code.
=> I used DPMI calls 0x204 and 0x205 to get/set interrupt vector but still failed before...

liaoo

unread,
Jul 28, 2012, 2:04:38 AM7/28/12
to
> He can use the 8259's until I/O APIC is enabled. I use them on machines
>
> with I/O APICs without ever using the I/O APICs. The 8259's are either
>
> present as hardware or emulated via BIOS or somesuch...

=> Does this means in DOS mode default mode is PIC(8259) mode, NOT APIC mode ? right ? (then I can focus on other aspects to solve my problem...)

> In an OS project of mine, I use the standard BIOS IRQ setup for my PICs.
>
> 0x08 for PIC1 and 0x70 for PIC2. Although, I do set them via ICW2
>
> just to make sure they are the values I expect.
>
>
>
> Most people say you need to remap the PICs since they are shared between
>
> interrupts and IRQ's. That's not actually true. You can determine what
>
> triggered a specific interrupt afterwards. It just takes more work:
>
>
>
> In an interrupt, you can check the instruction stream (IP saved on stack) to
>
> see if the last instruction was an INT instruction (0xCD). If so, the
>
> interrupt is a software interrupt, or it could be a fault. You can then
>
> check to see if the software interrupt number called matches the interrupt
>
> number you're in. If not, it's a fault, instead of a software interrupt.
>
> If the interrupt number is a possible IRQ interrupt, you can read the low or
>
> high PIC's ISR register to see if it was an IRQ. If so, the interrupt is an
>
> IRQ. The routine I use to separate these is more complicated than that, but
>
> that's the basic outline.

=> I will try to check and implement this if available...

liaoo

unread,
Jul 28, 2012, 2:38:54 AM7/28/12
to
Dear all,

I ever found 2 paragraphs about interrupt handling in DOS/32 Advanced web site and list as follows for reference...


1st: in http://dos32a.narechk.net/manual/index.html
---------------------------------------------------
Question #7:
Does DOS/32 Advanced support auto passup of hardware interrupts in range IRQ 8..15?

Answer #7:
Yes. DOS/32 Advanced built-in DPMI server will automatically allocate a callback for an IRQ when you install a protected mode handler for that hardware interrupt. The hardware interrupts in range IRQ 0..7 and 8..15 are always automatically passed up to the protected mode if the respective protected mode handlers are installed. Additionally you can manually allocate and install real mode callbacks by using DPMI functions 0303h and 0201h, which are natively supported by the DOS Extender.
---------------------------------------------------


2. in http://dos32a.narechk.net/manual/index.html
---------------------------------------------------
When you install a protected mode IRQ handler, the DOS Extender will automatically install a special real mode IRQ callback, which will send the IRQ occurred in the real mode to a protected mode interrupt handler. Unlike DOS/4GW which supports this technique only for the first eight IRQs (IRQs 0-7 = INTs 08-0Fh), DOS/32 Advanced will install real mode IRQ callbacks for all 16 hardware interrupts (IRQ 0-7, IRQ 8-15 = INT 08-0Fh, INT 70-77h). Further more DOS/32 Advanced is capable of trapping the software interrupts that have been issued to emulate IRQs in protected mode.
---------------------------------------------------


Thus can I say with DOS/32a(DPMI host in it) the only thing I should do for hooking interrupt is just install the PM handler by DPMI calls(0x204 and 0x205) ? ( and then DOS/32a will automatically create the callback for RM, and no matter CPU is in which mode there is always ISR for it...)

Besides someone said you just ONLY provide the handler for PM and when CPU is in real mode dos extender will auto "pass up" to protected mode then PM handler is invoked...(of course the price is: speed...! )

Is it correct ?

Rod Pemberton

unread,
Jul 28, 2012, 5:06:25 AM7/28/12
to
"liaoo" <jimmy...@gmail.com> wrote in message
news:2c7c72eb-f9a5-4d00...@googlegroups.com...
...

[from the other post]

> => Does this means in DOS mode default mode is PIC(8259) mode,
> NOT APIC mode ? right ? (then I can focus on other aspects to solve
> my problem...)
>

Yes. (I believe so.)

> > The mention of DOS32/A suggests this is a DPMI application. Are you
> > compiling for 16-bit RM DOS as "wcl/l=dos" or for 32-bit DOS PM DPMI
> > as "wcl386/l=dos4g" ?
>
> => I have some questions about above statement and please point out
> the mistakes for corrections because I am the newbie on DOS extender...
>
> First after checking "all" my makefiles I found keyword "dos4g" is
>NOT used. The content of my "main" make file is as follows(part):

It appears you're using 'wpp386' which is the compiler for C++ where the
target is os2 ("/l=os2") and using 'wlink' to link.

Is this for OS2? I assumed this was for DOS because of the DOS32/A ... Or,
is this for DOS because of the DOS32/A but via OS2 objects ... ?

Well, there's no C++ equivalent to the 'wcl386' combination (i.e., PM C
compiler 'wcc386' and linker 'wlink'). If there was an equivalent of
'wpp386' and 'wlink', it'd be named wpl386'. If it did exist, what you're
basically doing with your link files is 'wpl386/l=os2' and then stubbing
with DOS32/A. See the "wc*.exe" and "wp*.exe" files in 'binw'.

> Thus I will say I found no "dos4g" in my makefile...! Could I ask
> why "wcl386/l=dos4g" is required if installing PM handler ?

As you can see from your link files, it's definately not required. I was
just trying to find out if you were building a 16-bit DOS or 32-bit DPMI
application. It seems you're building for OS2 and DOS DPMI?

The "/l=dos4g" is the default way of building a DPMI application for DOS.
I'm not familiar with OS2. From what I gather, OS2 might support two types
of 32-bit applications: 32-bit OS2 applications and DOS DPMI (32-bit). But,
I'm not sure...

You're using 'stub' directive in one of the linker files to build using
DOS32/A as a replacement stub. You could also unstub DOS4GW
and restub with DOS32/A.

> Second I want to know why using "dos4g" instead of "dos32a" ?
> (I am using DOS/32a and not dos4g or dos4gw...)

DOS4GW comes with OpenWatcom. OpenWatcom also has command line
options ("/l=dos4g") to build for it for 'wcl386' (C not C++). See pguide.

> Do I lose something ?

No, I think your setup is probably correct. I made some assumptions about
your setup. Because of wpp386, you probably had to use linker files to
link, since there is no "wpl386".

I would question why you're building a DOS and DPMI application by stubbing
an OS2 LE. I don't understand that. OpenWatcom will build for DOS and
build DOS4GW (DPMI) applications directly. So, if you're not using OS2,
you might consider reworking your linker files.

Someday, you might try changing the "format os2 le" to "format dos" and
adding a "system dos4g". The "system" directive has a number of OS2 options
also. See lguide.

> => Does above mean: I have to setup both the PM and RM handlers, that is,
> bimodal interrupt support ?

No, but you can, if that's needed...

Most of the time, you only need one interrupt routine and usually only for
one mode, either RM or PM but typically not both. Sometimes, you need a
routine for both modes (PM and RM). For that, you'll install one handler if
one is not already installed (i.e., BIOS interrupt). Then, you'll install a
callback for the other handler. The callback switches modes and calls the
other handler in the other mode. You only need two handlers if the RM and
PM routines need to be different or the two handlers have identical
functionality for speed. I.e., RM interrupt calls BIOS and PM interrupt is
custom code or has debugging info or you need to eliminate callback
overhead.

E.g., if you're using the a BIOS RM interrupt routine for an interrupt and
you need the routine for PM too, you'll install a callback for PM. So, if
an interrupt occurs in RM, the original RM routine is called. If an
interrupt occurs in PM, the PM interrupt routine switches to RM and calls
the RM interrupt. Once finished, it returns to PM.

E.g., if you're installing an interrupt for PM and there is no RM interrupt
routine, you'll install a callback for RM. So, if an interrupt occurs in
PM, then the PM interrupt routine is called. If an interrupt occurs in RM,
the RM interrupt switches to PM and calls the PM routine. Once finished, it
returns to RM.

So, for any interrupt with DPMI:

RM interrupt routine - no PM interrupt routine (*)
RM interrupt routine - PM callback (calls RM interrupt)
no RM interrupt routine - PM interrupt routine
RM callback (calls PM interrupt) - PM interrupt routine
RM interrupt routine - PM interrupt routine
no RM interrupt routine - no PM interrupt routine (**)

(*) usually the default, i.e., for BIOS and DOS interrupts in RM
(**) default for RM interrupts without a routine

Whether the RM or PM interrupt is called depends on which mode the cpu is in
when the interrupt occurs. With DPMI, the DPMI host is switching between RM
and PM, repeatedly, quickly. Some of this is because there are a few
interrupts that are redirected per the DPMI specification. For DPMI
applications, many of the interrupt routines that people use are BIOS and
DOS which are RM interrupts. So, using a PM callback to RM is common. PM
interrupt routines have to be written by you, just like additional RM
interrupt routines. Or, PM callbacks have to be installed by you. Except
for DPMI calls, no interrupts are installed in PM. You must do it.

> => I did not use the int386x() but I used assembly language
> by #pragma aux ... to implement DPMI calls(int 31h)

That'll work. I prefer what's provided by OpenWatcom when available. I
hope that's more compatible, more complete, more tested, etc. #pragma aux
the last time I looked was thoroughly undocumented and had some quirks.
Also, for DJGPP, I noticed some of the DPMI assembly routines were quite
large.

> => I used DPMI calls 0x204 and 0x205 to get/set
> interrupt vector but still failed before...

Well, good luck. Start simple. Test RM. Test PM.

I personally had a variety of issues when first attempting DPMI. I just had
to work through them. I found I had problems with certain DJGPP functions,
but others worked well. So, I avoid those. DPMI does have some intracies
too, especially if accessing via assembly. E.g., wrong mode, saving stacks,
...


Rod Pemberton









liaoo

unread,
Jul 28, 2012, 8:52:21 AM7/28/12
to
Dear Rod Pemberton,
Thanks first for your lots of valuable information/experience and I think I have to take some time to absorb and verify it.

Honestly speaking I did not know exactly what the term "format os2 le" means because this link file is copied from some sample on internet...Maybe I should figure it out first !

Besides, I think there might be no need to write low-level code to access hardware Ex. 8259 because the "DOS extender" I used should provide some APIs(interface) and then complex interrupt handling are "transparent" to users...

Regards,
liaoo

liaoo

unread,
Aug 14, 2012, 11:15:29 PM8/14/12
to

This issue is solved and I summarize as below for reference:

First you have to check if HW interrupt is generated or not by following check points:
- PCI config space ID bit is 0 ? (Interrupt disable)
- PCI config space IS bit is 1 ? (Interrupt status)
- PCI config space Interrupt Line is valid value ? Ex. IRQ 3,4,5,7,9,10,11,12
- Interrupt Mode is APIC or PIC ?
- corresponding Interrupt Request/Status asserted in HW-level ?
Ex. for PIC mode, you can check both IRR(request) and IMR(mask) in "8259"

Second you have to do ISR replacement by using FP_SEG(),FP_OFF(), MK_FP() and DPMI calls 0x204 and 0x205 for get/set Interrupt Vector.

* Once you install the PM handler then DOS/32a will automatically install the RM handler, then there are totally 2 handlers for both real and protected modes !
* I used IRQ "3" and my newISR can be successfully called based on above

@ Detailed answer to this question is in http://stackoverflow.com/questions/11626049/replace-hw-interrupt-in-flat-memory-mode-with-dos32-a

Thanks for all your help !
0 new messages