[comp.binaries.ibm.pc.d] digitize bug / cheap fix

jbrown@jato.Jpl.Nasa.Gov (Jordan Brown) (04/07/89)

Play (and quite possibly record; haven't looked at it) has a bug in
its interrupt handling.

(First, of course, it's extremely ugly to assume register contents
between interrupt and non-interrupt code.  I understand why it's
done, though - there are less than 72 microseconds available per
iteration.  I think you might be able to be OK inside this, but it
would be close.  There's probably plenty of time at 8KHz, but as I
haven't built the board I can't opine on the sound quality.)

The problem arises (I think) when the key-up interrupt (from the RETURN
you pressed to invoke play) comes in after play starts, and then a timer
interrupt comes in on top of it.  The timer interrupt code does random
things to some registers and returns, and the poor keyboard code gets
in trouble.  I was seeing characters stuffed into the keyboard buffer;
I don't know what else could happen or what might happen on other BIOSes.

My fix is to disable all interrupts other than the timer interrupt for
the duration of the exercise.  This is obviously not the best solution,
but it works and was easy.  If I come up with something better (like
making the interrupt code well-behaved) I'll post it.

In theory, this fix doesn't work on PS/2s, because (I think) IRQ 0
could be shared.  Of course, I suspect the whole program goes down
in flames in that case.

A context diff follows...

*** play.asm  ***************
*** 79,85
  	MOV	WORD PTR OLDTMRINT,BX
  	MOV	WORD PTR OLDTMRINT+2,ES
  
! ;mask timer interrupt
  
  	IN	AL,21H
  	OR	AL,01H

--- 79,85 -----
  	MOV	WORD PTR OLDTMRINT,BX
  	MOV	WORD PTR OLDTMRINT+2,ES
  
! ;mask all interrupts
  
  	IN	AL,21H
  	push	ax
***************
*** 82,88
  ;mask timer interrupt
  
  	IN	AL,21H
! 	OR	AL,01H
  	OUT	21H,AL
  
  ;plug in the local timer interrupt routine

--- 82,89 -----
  ;mask all interrupts
  
  	IN	AL,21H
! 	push	ax
! 	OR	AL,0ffH
  	OUT	21H,AL
  
  ;plug in the local timer interrupt routine
***************
*** 159,166
  
  ;unmask timer interrupt
  
! 	IN	AL,21H
! 	AND	AL,0FEH
  	OUT	21H,AL
  
  ;figure out how long the system 18.2 Hz

--- 160,166 -----
  
  ;unmask timer interrupt
  
! 	pop	ax
  	OUT	21H,AL
  
  ;figure out how long the system 18.2 Hz