[rec.music.synth] MIDI interrupt I/O code problem

mpanek@polyslo.CalPoly.EDU (Michael Panek) (09/01/89)

   Thanks, Scott, for the encouragement and to those that responded.  Here's
the problem:  I copied this code from Electronic Musician, May 1989 and am 
trying to adapt it for general use.  Procedure "SendData" is flawed.  Not
understanding completely how MPU401 interrupts work, I need help.  There
seems to be a conflict between "MPU_interrupt_handler (INTERRUPT)" and
"SendData(midibyte:BYTE)".  I also don't understand under what
conditions an "INTERRUPT" procedure is called.

All help is greatly appreciated!
---------------------------------------------------------------------

CONST
   ACK                = $fe;  {254}
   data               = $330; {816}
   status             = $331; {817}
   command            = $331; {817}
   UART_mode          = $3f;  {63}
   reset_MPU          = $ff;  {255}
   interrupt_10       = 10;
   ReadyToSendData    = $80;  {128}
   ReadyToReceiveData = $40;  {64}

VAR
   CircularQ          : ARRAY[1..128] OF BYTE;
   head,tail          : WORD;
   old_int_vec        : POINTER;
   MPU_in_UART_mode   : BOOLEAN;

PROCEDURE disable_MPU_interrupts;
          INLINE($fa/$ba/$21/$00/$ec/$0c/$04/$ee/$fb);

PROCEDURE enable_MPU_interrupts;
          INLINE($fa/$ba/$21/$00/$ec/$24/$fb/$ee/$fb);

PROCEDURE ack_int_to_PIC;
          INLINE($ba/$20/$00/$b0/$20/$ee);

PROCEDURE MPU_interrupt_handler; INTERRUPT;
BEGIN
   disable_MPU_interrupts;
   WHILE ((Port[status] AND ReadyToSendData)=0) DO BEGIN
      CircularQ[head]:=Port[data];
      IF (head<128) THEN Inc(head) ELSE head:=1;
   END;{while}
   enable_MPU_interrupts;
   ack_int_to_PIC;
END;{pro MPU_interrupt_handler}

PROCEDURE SendData(midibyte:BYTE);
VAR       WhatToDo,byte1 : BYTE;
BEGIN
   disable_MPU_interrupts;
   REPEAT
      WhatToDo:=Port[status];
      IF ((WhatToDo AND ReadyToSendData)=0)
         THEN BEGIN
              byte1:=Port[data];
              IF (byte1<>ACK)
                 THEN BEGIN
                      CircularQ[head]:=byte1;
                      IF (head<128) THEN Inc(head) ELSE head:=1;
                 END;{then}
         END;{then}
      byte1:=Port[status];
   UNTIL (byte1 AND ReadyToReceiveData)=0;
   Port[data]:=midibyte;
   enable_MPU_interrupts;
END;{pro SendData}