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}