My main problem is quite strange. My code does play RAW files and it works perfect, until the file size is larger than my buffer.

In a DOS shell this code works to perfection. In true DOS it does not. The first two blocks play fine, that is the sound card does generate the interrupt once. After the first interrupt when it comes to the end of the next block, the interrupt is not generated.
Since I'm in single cycle DMA, the sound stops. The DMA is not reprogrammed nor is the DSP, the offset is not incremented, and everything hangs. Since I've hooked an interrupt and not unhooked it properly (since the code never comes to the end of the sound) the system is hosed and I must reboot to reset all the chips and to regenerate the interrupt vector table.


Two questions:
[ist][*]Why does the sound card only generate 1 interrupt? If I'm acknowleding all hanging ints and the PIC, it should continue to generate interrupts until the sound is done playing. It only works correctly in a Windows DOS box and I cannot figure out why.
[*]How do you rewrite a Ctrl-C handler? I know you can rewrite these handlers using signal(), but the syntax of the function is so cluttered(and the example code does not work) I cannot figure out how to do it. It is signal(SIGINT,(void)(*near)(int)) or something like that. If I can do this, then on CTRL-C I would uninstall my handler - thus I might not have to reboot every time.[/list]

If I can get this working, then I've finally written an SB16 module that works and can play very long samples. The sample I tested in the Windows DOS box was 800kb in length and it played flawlessly (except for clicking which I know how to fix). Once this works in real-mode, it's on to DJGPP and PM.

Some of this is directly from Ethan Brodsky's code so he deserves the credit

Code:
void interrupt newhandler(...)   
{
  //Check if sound is done - not the best/safest way to do it
  if (done==1) exit(EXIT_SUCCESS);   

  //Increment offset into file - globals again
  //ChunkSize is 32000 bytes
  fileoffset+=ChunkSize;   

  //Load data and get chunk size
  //Will be less than 32000 when near the end of the sound file
  unsigned int size=LoadData(fileoffset); 

  //Reprogram the DSP and DMA for next block and start playing
  PlayBuffer(size);       

  //Acknowledge SB - for 8 bit sound
  inp(DSPREADBUF);   

  //Acknowledge pic for int<8
  outp(0x20,0x20);    
}

void Shutdown(void)
{
  //Acknowledge PIC since caller could be an interrupt handler
  outp(0x20,0x20);   

  //Stop current sound - none should be playing at this point
  WriteDSP(0xD0);    

  //Restore the old handler to clean up the vector table  
  if(handlerinstalled==TRUE) UninstallHandler();  //Clean up

  //Reset the DSP for future use
  ResetDSP();

  //Close the file
  close(handle);        
}

void InstallHandler(void)
{
  //Disable interrupts (CLI)
  disable();
  
  //Mask the interrupt 
  outp(picmaskport, (inp(picmaskport)|irqstopmask));
  
  //Save the old handler for later restoration of vector table
  oldhandler=getvect(intvector);   //intvector is global for now
  
  //Install our handler
  setvect(intvector,newhandler);    
  
  //Unmask the interrupt
  outp(picmaskport,(inp(picmaskport)&irqstartmask));
  
  //Handler is installed
  handlerinstalled=TRUE;
  
  //Re-enable interrupts (STI)
  enable();
}

void UninstallHandler(void)
{
  //Disable interrupts (CLI)
  disable();
  
  //Mask
  outp(picmaskport,(inp(picmaskport)|irqstartmask));
  
  //Restore old handler
  setvect(intvector,oldhandler); 
  
  //Set flag to reflect change
  handlerinstalled=FALSE;
  
  //Enable interrupts (STI)
  enable();
}

unsigned int LoadData(unsigned long offset)
{
  //Check for end of sound file
  if (offset+32000L>filelength(handle) done=1;  
  
  //Get next chunk size
  unsigned long size=filelength(handle)-offset;

  //if larger than buffer size - clamp to buffer size
  if (size>32000L) size=32000;
  
  //read in size bytes
  read(handle,(int *)buffer,size);

return size;
}

This should be enough code to see what I'm doing. If not, I'll post my whole source later. Again, some variables are global and are not evident or declared in this snippet.