/*
	this is a program to test out the playing of background midi
	sequences
*/

#include <osbind.h>
#include <stdio.h>
#include "midi.h"

#define TRAPS 0x080
/*
	global variables
*/
kbdvecs *thevecs;
long old_vec;
long in_vec;
long old_trap;
int midi_stat;
char	om[512],im[4096];	/*	input and output midi buffers	*/

extern midi_vec();
extern mout();
extern Mymidi();
extern jump_tab();


init_buffers()
{
	MIDI_BUFFER *midi_buff;

	midi_buff = get_midi_out_rec();
	midi_buff->head = 0;
	midi_buff->tail = 0;
	midi_buff->size = 512;
	midi_buff->buffer = om;
	midi_buff = get_midi_in_rec();
	midi_buff->head = 0;
	midi_buff->tail = 0;
	midi_buff->buffer = im;
	midi_buff->size = 4096;
}

asm {		/*	this is the entry of midi IRQ handler	*/
uart_csr:
	dc.b	0;	/*	control shadow for urat CSR	*/
	dc.b	0;
inmidi:
	dc.l	0
	dc.w	0
	dc.w	0
	dc.w	0
	dc.w	0
outmidi:
	dc.l	0
	dc.w	0
	dc.w	0
	dc.w	0
	dc.w	0
/*
** The OS irq saves D0-D3,A0-A3,A5 so, I don't have to here
** as I had figured
*/
midi_vec:
	move.b	MIDI_CSR,D3		/*	get MIDI port status	*/
	btst.b	#7,D3				/*	was it a MIDI interrupt	*/
	beq.b	exit				/*	no, do keyboard	*/
	btst.b	#0,D3				/*	recieve interrupt	*/
	beq.b	next				/* not recieve, check xmit	*/
	bsr		mim				/*	handle midi in interrupt	*/
next:
	btst.b	#1,D3				/*	transmit interrupt	*/
	beq.b	exit
	bsr		mout				/*	do midi out	*/
exit:
	rts						/*	get out of here	*/
	/*
	** This is the midi in interrupt service routine
	*/
get_inrec:
	lea	inmidi(PC),A0
	move.l	A0,D0
	rte
mim:
	move.b	MIDI_DATA,D0
	lea	inmidi(PC),A0	/*	get the address of the input buffer des	*/
	movea.l	BUFFER(A0),A1	/*	address of buffer	*/
	move.w	TAIL(A0),D2		/*	index of data pointer	*/
	addq.w	#1,D2		/*	i = t+1	*/
	cmp.w	SIZE(A0),D2	/*	i >= current size?	*/
	bcs.b	mim01
	moveq	#0,D2
mim01:
	cmp.w	HEAD(A0),D2		/*	do we need to wrap?	*/
	beq.b	mim_exit
	move.b	D0,0(A1,D2)		/*	store data into buffer	*/
	move.w	D2,TAIL(A0)		/*	save the index	*/
mim_exit:
	rxit:
	rxit:
	rxit:
	rxit:
	r                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *	get midi out descriptor	*/
	ori.w	#0x700,SR	/*	disable the interrupts	*/
	move.b	(A2),D0
	btst.l	#1,D0	/*	is transmit buffer full?	*/
	beq.b	mio1		/*	xmit full, put into circ buffer	*/
	move.w	HEAD(A0),D2
	cmp.w	TAIL(A0),D2	/*	head == Tail?	*/
	bne.b	mio1		/*	no, so branch		*/
	move.b	D1,MIDI_DATA	/*	put data into UART	*/
	lea		uart_csr(PC),A1
	ori.b	#ENABLE_TX,(A1)
	move.b	(A1),(A2)
	bra		mio3
mio1:
	move.w	TAIL(A0),D2	/*	get current tail pointer	*/
	addq.w	#1,D2		/*	i = t+1	*/
	cmp.w	SIZE(A0),D2	/*	i >= current size?	*/
	bcs.b	mio01
	moveq	#0,D2
mio01:
	cmp.w	HEAD(A0),D2	/*	head = tail?	*/
	beq.b	mio2		/*	no space left	*/
	move.l	BUFFER(A0),A1	/*	pointer to Data Buffer	*/
	move.b	D1,0(A1,D2)		/*	store data to buffer	*/
	move.w	D2,TAIL(A0)		/*	SAVE tail pointer	*/
mio3:
	moveq	#0,D0
	move	(A7)+,SR	/*	enable interrupts	*/
	rte
mio2:	/*	this means bad output	*/
	moveq	#-1,D0
	move	(A7)+,SR	/*	enable interrupts	*/
	rte
midinstat:
	rte
midputstat:
	rte
ms_write:
	/*
	** this routine real fast like, put a midi string into the
	** buffer for output on the midi port.  Interrupts are disabled
	** durring this operation, but we are going for all out speed
	** here so this routine should not take long to execute
	**
	** A0 will contain the address of the output midi descriptor
	** A1 is the base address of the UART
	** A2 is the address of the output string
	** A3 will point to the output buffer
	** A4 used to point to CSR shadow
	** D1 is the lenth of the string
	*/
	move 	SR,-(A7)		/*	save status reg	*/
	lea		MIDI_CSR,A1
	lea		outmidi(PC),A0	/*	get midi out descriptor	*/
	ori.w	#0x700,SR		/*	disable the interrupts	*/
	move.b	(A1),D0
	btst.l	#1,D0			/*	is transmit buffer full?	*/
	beq.b	msw1			/*	xmit full, put into circ buffer	*/
	move.w	HEAD(A0),D2
	cmp.w	TAIL(A0),D2		/*	head == Tail?	*/
	bne.b	msw1			/*	no, so branch		*/
	move.b	(A2)+,2(A1)		/*	put data into UART	*/
	subq	#1,D1			/*	subtract one from lenth	*/
	lea		uart_csr(PC),A4
	ori.b	#ENABLE_TX,(A4)
	move.b	(A4),(A1)		/*	Enable Uart interrupts	*/
msw1:
	/*
	** Ok, we can really scream here, so download this sucker, FAST!
	*/
	move.l	BUFFER(A0),A3	/*	pointer to Data Buffer	*/
	move.w	TAIL(A0),D2	/*	get current tail pointer	*/
	move.w	SIZE(A0),D0
	move.w	HEAD(A0),D3
lmsw1:
	addq.w	#1,D2		/*	i = t+1	*/
	cmp.w	D0,D2	/*	i >= current size?	*/
	bcs.b	msw01
	moveq	#0,D2
msw01:
	cmp.w	D3,D2	/*	head = tail?	*/
	beq.b	msw2		/*	no space left	*/
	move.b	(A2)+,0(A3,D2)		/*	move data	*/
	dbf		D1,lmsw1			/*	keep on looping	*/
	move.w	D2,TAIL(A0)		/*	save index	*/
msw3:
	moveq	#0,D0
	move	(A7)+,SR	/*	enable interrupts	*/
	rte
msw2:	/*	this means bad output	*/
	moveq	#-1,D0
	move	(A7)+,SR	/*	enable interrupts	*/
	rte
	/*
	** This is the jump table for the midi handler
	*/
disable_interrupts:
	ori.w	#0x700,SR		/*	disable the interrupts	*/
	rte
enable_interrupts:
	andi.w	#0xf8ff,SR		/*	enable the interrupts	*/
	rte
jump_tab:
	dc.l	midin
	dc.l	midput
	dc.l	midinstat
	dc.l	midputstat
	dc.l	get_inrec
	dc.l	get_outrec
	dc.l	ms_write
	dc.l	disable_interrupts
	dc.l	enable_interrupts
}

put_midi(a)
int a;
{
	asm	{
	move.w	a(A6),D1
	moveq	#MIDIPUT,D0	/*	put function number	*/
	trap	#3
	}
}

get_midi()
{
	asm	{
	moveq	#MIDIGET,D0	/*	get function number	*/
	trap	#3
	}	/*	this will return with data in D0	*/
}

init_traps()
{
	old_trap = Setexc(35,Mymidi);
}

restore_traps()
{
	Setexc(35,old_trap);
}

midi_init()
{
	init_traps();	/*	enable trap 3 for our use	*/
	init_buffers();
	init_midput();
	init_vecs();
}

midi_cleanup()
{
	restore_vecs();
	restore_traps();
}

init_vecs()
{
	thevecs = (kbdvecs *)Kbdvbase();	/*	get 6850 irq vectors	*/
	old_vec = (long)thevecs->midisys;
	thevecs->midisys = midi_vec;
}

restore_vecs()
{
	thevecs = (kbdvecs *)Kbdvbase();
	thevecs->midisys = (int(*)())old_vec;
}

irq_en()
{
	asm	{
		moveq	#ENABLE_INTERRUTS,D0
		trap	#3
	}
}

irq_dis()
{
	asm {
		moveq	#DISABLE_INTERRUTS,D0
		trap	#3
	}
}

midi_ws(len,buff)
int len;
char *buff;
{
	asm {
		moveq	#MIDIWS,D0		/*	write string function #	*/
		movea.l	buff(A6),A2		/*	pointer to midi buffer	*/
		move.w	len(A6),D1		/*	lenth of midi buffer	*/
		trap	#3
	}
}

MIDI_BUFFER *get_midi_out_rec()
{
	asm	{
	moveq	# GET_MIDOUTREC,D0	/*	get function number	*/
	trap	#3
	}	/*	this will return with data in D0	*/
}

MIDI_BUFFER *get_midi_in_rec()
{
	asm	{
	moveq	# GET_MIDINREC,D0	/*	get function number	*/
	trap	#3
	}	/*	this will return with data in D0	*/

}

