Doing a read while in an intr handler

This is a discussion on Doing a read while in an intr handler within the A Brief History of Cprogramming.com forums, part of the Community Boards category; I'm writing a sound system for DOS real mode. The program hangs under DOS when the interrupt is generated. Can ...

  1. #1
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,596

    Doing a read while in an intr handler

    I'm writing a sound system for DOS real mode. The program hangs under DOS when the interrupt is generated. Can you do a read() inside of an interrupt or will this cause DOS to re-enter itself?

    Problem is that real mode cannot just load all of the samples into memory all at once so I'm caching from the disk. Each sample has a 8192 bytes buffer to cache with. The DMA transfer is 4096 bytes. Slow because of the read(), but the other alt is EMS which is not hard, but haven't done it yet.

    So on interrupt I'm reading in a new block of data in the block that just played, mixing it, and playing the block that was just loaded. The read() is causing the system to freeze with the disk hard disk light on. When I comment it out, everything works and I send ACK to the DSP and EOI to the PIC and everyone gets along fine.

    If I cannot read while inside of an interrupt (also cannot do a printf()) then I guess I will have to go PM or use EMS.

    Is there any other way to do this?

    I think DOS is re-entering itself but I cannot CLI because read requires a DOS interrupt just like printf. Since both of these functions cause the system to crash and will even bring Windows to its knees this is my take on what's happening.

    No errors or warnings in compile and circular buffer works fine.

    Buffer:

    ...>(Start)---------------->(1)Interrupt-------------->(2)Interrupt>...



    At point 1 I set the PlayOffset to 4096 and the LoadOffset to 0.
    Load all samples from their respective files and mix all sample buffers into one global sample output buffer.

    At point 2 I set the PlayOffset to 0 and the LoadOffset to 4096.
    Load all samples from their respective files and mix all sample
    buffer into one global sample output buffer.

    The whole cycle continues until done playing(point 2 is the same as the start point of the diagram).

  2. #2
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,592
    From within an ISR, you should be looking to do as little work as possible, and you shouldn't be calling something like read(), which takes a long time, and also re-enters DOS (as you've already noted). Basically, anything which could block, take a long time, or calls DOS is probably a no-no.

    The normal way (I think) is a double buffer arrangement, where the ISR just reads from one buffer, and when that's done, flips over to the other.
    A periodic check inside your main program detects this change, and issues the read request to fill the now vacant buffer, hopefully before the ISR reaches the end of the previous buffer.

    The size of the buffer depends on
    a) how fast the ISR gets through the data
    b) how fast you poll for a change of buffer, to trigger the re-fill
    c) how fast the buffer can be filled with a read() call.

  3. #3
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,596
    Well, my sound system does work in a DOS shell, but not in pure DOS. The read() does cause DOS to re-enter itself and the whole thing comes crumbling down. I'm only reading 256 bytes and transferring half that to the DMA using a circular buffer. I altered my buffering structure a bit from my last post. The handler loads into the block that just played while the DMA is set to auto init. It just loops and loops while my int handler fills the block that just played with info from the sample. Fill behind and play ahead. So, once the DMA is set in motion it will not stop until I stop it at the end of the longest sample in the mix. The DMA automatically loops so I never have to reprogram it, thus stopping the sound.

    So far it works great and can mix an unlimited number of samples with very good audio quality. Of course, the more samples, the quicker the values will go out of range and possibly cause distortion. Only occurs when there are more than 8 or 9 samples playing at once.

    Since my DMA buffer is so small, you can add samples to the mix almost at any time since it takes almost nothing to transfer 256 bytes.

    I'll try to implement what you said, though, so it will work in pure DOS.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. What Would You Use To Read User Input?
    By djwicks in forum C Programming
    Replies: 11
    Last Post: 04-05-2005, 03:32 PM
  2. Replies: 3
    Last Post: 03-04-2005, 01:46 PM
  3. I am lost on how to read from file and output to file?
    By vicvic2477 in forum C++ Programming
    Replies: 4
    Last Post: 02-27-2005, 10:52 AM
  4. Read Array pro!!Plz help!!
    By Supra in forum C Programming
    Replies: 2
    Last Post: 03-04-2002, 02:49 PM
  5. Help! Can't read decimal number
    By Unregistered in forum C Programming
    Replies: 2
    Last Post: 09-07-2001, 02:09 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21