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}