Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to index page
Thread view  Board view
myrkraverk

13.12.2012, 19:39
 

Basics of interrupt chaining? (Developers)

Hi all,

There was a previous discussion about interrupt chaining here, but that just confused me more.

For context, I'm still programming the Sound Blaster, so I'm doing an IRQ 7 (for DOSBox) hardware interrupt handler.

What is the basic method of chaining an interrupt? From what I've gathered, I can't just place the segment:offset in registers and JMP, but have to store the IP and CS in memory (in this order) and then far jump by a pointer reference.

Or is CALL better?

Here is the code I've come up with for this. This is WASM btw in the tiny model, hence cs=ds.

Am I on the right track?


        ;; Load IRQ 7 handler.
        mov     ah, 0x37
        mov     al, 0x07        ; In DOSBox, the SB uses IRQ 7.
        int     0x21
        ;; Now es=code segment, bx=instruction pointer
        ;; And save in pointer
        mov     irq_handler, bx
        mov     irq_handler+2, es

        ;; Save our IRQ 7 handler
        lea     dx, sb_interrupt
        mov     cx, cs          ; redundant since ds
        mov     ds, cx          ; hasn't been modified
        mov     ah, 0x25
        mov     al, 0x07        ; again, redundant but explicit.
        int     0x21

; [snip]

        sb_interrupt proc
                jmp far ptr irq_handler

                irq_handler     dw      0,      0
        sb_interrupt    endp

myrkraverk

13.12.2012, 20:19

@ myrkraverk
 

Basics of interrupt chaining?

I just noticed my first mov instruction should have been ah, 0x35.

Japheth

Homepage

Germany (South),
13.12.2012, 21:31

@ myrkraverk
 

Basics of interrupt chaining?

[quote]
sb_interrupt proc
jmp far ptr irq_handler

irq_handler dw 0, 0
sb_interrupt endp
[/quote]

I'd say it should be either

        sb_interrupt proc
                jmp dword ptr cs:[irq_handler]
                irq_handler     dw      0,      0
        sb_interrupt    endp

or

        sb_interrupt proc
                db 0EAh   ;opcode for jmp SSSS:0000
                irq_handler     dw      0,      0
        sb_interrupt    endp

---
MS-DOS forever!

myrkraverk

14.12.2012, 02:58

@ Japheth
 

And now: int 0x21 in hw interrupt handler?

Thank you Japheth.

And now I have a different question: What issues will or can I run into when calling int 0x21 inside my interrupt handler?

In this case, I'm thinking of using it to load PCM data from a file to the DMA buffer. This means ah = 0x3f; int 0x21. I assume there might be two issues: reentrancy and time (loading from a file can take while I suppose).

Context. I'll be using the DMA controller in repeat mode and after each half of the buffer, the SB will issue IRQ 7 so I can fill the other half with new data = double buffering.

I read somewhere that int 0x21 are not reentrant so using it inside IRQ 7 might be a bad idea since it can be flagged while DOS is already servicing 0x21, right?

The only thing I can think of is busy waiting for a flag toggled in the IRQ handler. Is there anything else I can do?

Japheth

Homepage

Germany (South),
14.12.2012, 06:10

@ myrkraverk
 

And now: int 0x21 in hw interrupt handler?

> Thank you Japheth.
>
> And now I have a different question: What issues will or can I run into
> when calling int 0x21 inside my interrupt handler?

Calling DOS from inside a hardware interrupt handler is usually not a good idea. Although, if your program is to work in DOSBox only, this strategy may work without problems.

> In this case, I'm thinking of using it to load PCM data from a file to the
> DMA buffer. This means ah = 0x3f; int 0x21. I assume there might be two
> issues: reentrancy and time (loading from a file can take while I
> suppose).

Yes.

> I read somewhere that int 0x21 are not reentrant so using it inside IRQ 7
> might be a bad idea since it can be flagged while DOS is already servicing
> 0x21, right?
>
> The only thing I can think of is busy waiting for a flag toggled in the IRQ
> handler. Is there anything else I can do?

I suggest to read the PCM data into a large XMS buffer when it is safe to read files. During interrupt time it's ok to access XMS data.

---
MS-DOS forever!

tom

Homepage

Germany (West),
14.12.2012, 18:25

@ myrkraverk
 

And now: int 0x21 in hw interrupt handler?

> And now I have a different question: What issues will or can I run into
> when calling int 0x21 inside my interrupt handler?
literally ALL kind of issues; DOS was not designed for that.

take
http://http://en.wikipedia.org/wiki/Terminate_and_Stay_Resident
as a starter, but be prepared for a VERY steep learning curve.

bretjohn

Homepage E-mail

Rio Rancho, NM,
15.12.2012, 01:29

@ myrkraverk
 

And now: int 0x21 in hw interrupt handler?

> The only thing I can think of is busy waiting for a flag toggled in the IRQ
> handler. Is there anything else I can do?

As Japheth and Tom have both eluded to, trying to call INT 21h from inside an IRQ handler is a REALLY bad idea. Sometimes it's possible, and sometimes it's not. You really shouldn't even try unless you have no other choice.

Japheth's suggestion is probably the easiest to implement. You just need some kind of a memory buffer, though it doesn't necessarily need to be in XMS. You need to have one process that reads the file when it's safe to do (definitely not from inside an IRQ handler), and puts data into the buffer. As a separate process, you extract data from the buffer in the IRQ handler. Obviously, you need some sort of "communication" between the two (independent) processes to manage the buffer.

myrkraverk

15.12.2012, 15:52

@ bretjohn
 

And now: int 0x21 in hw interrupt handler?

> As Japheth and Tom have both eluded to, trying to call INT 21h from inside
> an IRQ handler is a REALLY bad idea. Sometimes it's possible, and
> sometimes it's not. You really shouldn't even try unless you have no other
> choice.

Here is something I got in the email, from Eric:

> You want to check the INDOS flag to see if int21
> is already busy. Also you want to check if your
> own handler is already busy and you may want to
> enable IRQ at some point, normally they are off
> until your IRQ handler finishes. But there are
> many howtos about such things on the web :-)

Another "option" might be to wrap all my int 0x21 calls with CLI/STI but I'm not sure that's a good idea either.

> Japheth's suggestion is probably the easiest to implement. You just need
> some kind of a memory buffer, though it doesn't necessarily need to be in
> XMS. You need to have one process that reads the file when it's safe to do
> (definitely not from inside an IRQ handler), and puts data into the buffer.
> As a separate process, you extract data from the buffer in the IRQ
> handler. Obviously, you need some sort of "communication" between the two
> (independent) processes to manage the buffer.

Yes, I can either busy wait for the interrupt, using some sort of semaphore, or manipulate the stack in a fashion that IRET will bring me to an application level handler [thread, in a sense] which then returns control to the program where the IRQ was raised.

For now the question is: what do I want to do while the PCM data is being fed to the Sound Blaster. If nothing, I can busy wait - something that might be a good idea as a "first try."

Maybe a more "sane" general way is to simply check in my main loop if audio needs processing [the same semaphore as before] and then feed in the next PCM data.

bretjohn

Homepage E-mail

Rio Rancho, NM,
17.12.2012, 18:08

@ myrkraverk
 

And now: int 0x21 in hw interrupt handler?

> > You want to check the INDOS flag to see if int21
> > is already busy. Also you want to check if your
> > own handler is already busy and you may want to
> > enable IRQ at some point, normally they are off
> > until your IRQ handler finishes. But there are
> > many howtos about such things on the web :-)

The InDOS flag is one of a few different checks you need to make to test whether DOS is already doing something or not. The problem is, what do you do if it's not safe? Your only option is to wait until it is safe, and that can never happen until you exit the IRQ handler. So, you need to have another process to download the data anyway, so you might as well just do it that way from the beginning.

Another possibility would be to do the checking in the IRQ and, if it's safe, to download way more data than you need (in case during the next IRQ it is not safe). The problem with that, though, is what happens if it is not safe and the correct data has not been downloaded yet? You in the same boat as above, and still need a separate process.

> Another "option" might be to wrap all my int 0x21 calls with CLI/STI but
> I'm not sure that's a good idea either.

That won't help, since the INT 21h handle will issue STI/CLI combinations at various times itself.

> For now the question is: what do I want to do while the PCM data is being
> fed to the Sound Blaster. If nothing, I can busy wait - something that
> might be a good idea as a "first try."

I've never done any sound stuff myself, so don't know for sure how it works. But, I assume that when you tell the sound blaster to play something, it does it, and then generates an IRQ when it is done. Inside the IRQ handler you can tell it what to do next, after which it will generate another IRQ. And so on.

IOW, you can do anything you want to in the foreground (screen animations or whatever) while the sound is processed in the background with the hardware/IRQ process. It could be difficult to maintain synchronization with the different processes, though.

myrkraverk

18.12.2012, 20:16

@ bretjohn
 

And now: int 0x21 in hw interrupt handler?

> The InDOS flag is one of a few different checks you need to make to test
> whether DOS is already doing something or not. The problem is, what do you
> do if it's not safe? Your only option is to wait until it is safe, and
> that can never happen until you exit the IRQ handler. So, you need to have
> another process to download the data anyway, so you might as well just do
> it that way from the beginning.

If I write the app in a way that it never calls int 0x21 while my IRQ handler
is active, am I safe? Are there other interrupts I must also not call?
BIOS, something else?

At the moment, I'm not sure I'll do any kind of visual feedback, but I can do
that by writing directly to the video memory.

tom

Homepage

Germany (West),
19.12.2012, 15:54

@ myrkraverk
 

And now: int 0x21 in hw interrupt handler?

> > The InDOS flag is one of a few different checks you need to make to test
> > whether DOS is already doing something or not. The problem is, what do
> you
> > do if it's not safe? Your only option is to wait until it is safe, and
> > that can never happen until you exit the IRQ handler. So, you need to
> have
> > another process to download the data anyway, so you might as well just
> do
> > it that way from the beginning.
>
> If I write the app in a way that it never calls int 0x21 while my IRQ
> handler
> is active, am I safe?
no.
> Are there other interrupts I must also not call?
> BIOS, something else?
dont't call anything.
DOS, BIOS, and basically everything else is NOT reentrant.
doing more then setting a flag at interrupt time is a certain recipe for interesting things to happen ;)
calling XMS to copy some memory (as Japheth suggested) is one of the few exceptions.


> At the moment, I'm not sure I'll do any kind of visual feedback, but I can
> do that by writing directly to the video memory.
actually THIS IS one of the few things safe to do

bretjohn

Homepage E-mail

Rio Rancho, NM,
14.12.2012, 19:43

@ myrkraverk
 

Basics of interrupt chaining?

> Or is CALL better?

Most of the time, for IRQ (hardware interrupt) handlers a JMP is better than a CALL. There are special circumstances (usually timing related) where you may need to use a CALL, though. When that happens, things get complicated -- you may need to queue requests and process them later time, or sometimes you may even be able to ignore requests and not process them at all. It just depends on exactly what the application requires.

For your particular application, though, you probably don't need to worry about any of that.

Back to index page
Thread view  Board view
22049 Postings in 2034 Threads, 396 registered users, 231 users online (0 registered, 231 guests)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum