/*#> */

/*$Author:   DCODY  $*/
/*$Date:   27 Jun 1992 15:44:28  $*/
/*$Header:   W:/sccs/midi/midi.c_v   1.2   27 Jun 1992 15:44:28   DCODY  $*/
/*$Log:   W:/sccs/midi/midi.c_v  $
 * 
 *    Rev 1.2   27 Jun 1992 15:44:28   DCODY
 * Made it test both input, output, and interrupts.
 * 
 *    Rev 1.1   25 Jun 1992 21:47:22   DCODY
 * PAS2 update
 * 
 *    Rev 1.0   15 Jun 1992 10:42:56   BCRANE
 * Initial revision.
*/
/*$Logfile:   W:/sccs/midi/midi.c_v  $*/
/*$Modtimes$*/
/*$Revision:   1.2  $*/
/*$Workfile:   midi.c  $*/

/*#<*/

;	/*\
;---|*|----====< MIDI.C >====----
;---|*|
;---|*| Demonstration MIDI I/O code
;---|*|
;---|*| Media Vision, Inc. Copyright (c) 1992. All Rights Reserved
;---|*|
;	\*/


#include <stdio.h>
#include <stdlib.h>
#include "mvmidi.h"

		// buffer storage for testing buffer I/O routines

#define BUFFLEN 100
		char buff100[BUFFLEN];	// buff used to send/receive data
		extern _MidiInFilter;

		// mode of operation

#define OUTPUTMODE 0x08
#define INPUTMODE  0x04
#define BLOCKMODE  0x02
#define IRQMODE    0x01
		int Mode		= 0;
		int EnableMode	= 0;

		// for debug output in realtime

		char far *VidPtr = 0xb8000000;
		char vidattr	 = 0x2F;

main(argc,argv)
	int argc;
	char *argv[];
{
int n,count;
unsigned int c;
char *b;

	// process command line switches

		Commandline (argc,argv);

	// install & initialize the MIDI stuff

		mvMIDIEnable(EnableMode);
		_MidiInFilter = 0;

    // receive data & display it...

		switch (Mode & (INPUTMODE|OUTPUTMODE)) {

			case INPUTMODE:

                while (1) {

					// fill the buffer with incrementing values

					count = mvMIDIGetBuff(BUFFLEN,(b = &buff100[0]));

					if (count) {
						while (count--)
							doprintit (*b++);
						 // printf ("%02x  ",*b++ & 0xff);
					}

					if ((c = mvMIDIGetByte()) < 256)
						doprintit (c);
					 // printf ("%02x  ",c);

					if (kbhit())
						DoExit(-1);

				}

			case OUTPUTMODE:

				while (1) {

					// fill the buffer with incrementing values

					for (n=0;n<BUFFLEN;n++)
						buff100[n] = c++;

					mvMIDISendBuff(BUFFLEN,&buff100[0]);

					mvMIDISendByte( (char) c++ );

					if (kbhit())
						DoExit(-1);

				}
				break;
		}
}


;	/*\
;---|*|----====< CommandLine >====----
;---|*|
;---|*| process the command line switches
;---|*|
;	\*/

int CommandLine(argc,argv)
    int argc;
    char *argv[];
{
char *s;
int n,temp;
long l;

		// the mode determines what we do in the main loop

		n = 1;
        while (n < argc) {

            s = argv[n++];

			if (*s == '/') s++;
			if (*s == '-') s++;

            switch (*s & 0x5f) {

                case 'B':
					Mode  |= BLOCKMODE;
					break;

				case 'O':
					Mode  |= OUTPUTMODE;
					break;

                case 'I':
					Mode  |= INPUTMODE;
					break;

				case 'Q':
					Mode  |= IRQMODE;
					break;

            }
        }

	/* if no mode, just give helps and exit 							*/

		if (!Mode) {
			printf ("\nMedia Vision MIDI test program.\n\n");
			printf ("To Use: DOS>MIDI [I] [O] [B] [Q]\n\n");
			printf ("Where:  [I] for input testing.\n");
			printf ("        [O] for output testing.\n");
			printf ("        [B] for block I/O testing.\n");
			printf ("        [Q] for using interrupts (polls by default).\n\n");
			printf ("Type any key to exit the test.\n\n");
			DoExit(0);
		}


	/* set the interrupt modes											*/

		if ((Mode & INPUTMODE) & (Mode & IRQMODE))
			EnableMode |= 1;

		if ((Mode & OUTPUTMODE) & (Mode & IRQMODE))
			EnableMode |= 2;

}


;	/*\
;---|*|----====< DoExit >====----
;---|*|
;---|*| Disable the MIDI and exit to DOS
;---|*|
;	\*/

DoExit(cc)
   int cc;
{

	// kill the midi port

		mvMIDIDisable();
		exit(cc);
}

;	/*\
;---|*|----====< shifts >====----
;---|*|
;---|*| Return -1 if any shift key (CTRL|ALT|LSHIFT|RSHIFT) is down
;---|*|
;	\*/

int shifts()
{
	_asm {

		push	es
		sub 	ax,ax
		mov 	es,ax
		mov 	al,es:[0x417]
		pop 	es
		and 	al,0Fh
		neg 	al
		sbb 	ax,ax
	}
}


;   /*\
;---|*|----====< doprinit >====----
;---|*|
;---|*| print a hex byte directly to the screen.
;---|*|
;	\*/

doprintit (char c)
{
	_asm {
			push	es
			push	di

			les 	di,[VidPtr]
			mov 	ah,[vidattr]		; get the attribute
		;
		; print the whole word and space
		;
			mov 	al,c
			and 	al,0F0h
			mov 	cl,4
			shr 	al,cl
			call	prtit

            mov     al,c
			and 	al,0FH
			call	prtit

			mov 	al,20h			; pad two spaces...
			call	int1014
            call    int1014

			cmp 	di,808h-1
			sbb 	ax,ax
			and 	di,ax
			not 	ax				; flip an attribute bit
			and 	al,10h			; when the pointer rolls
			xor 	[vidattr],al	; over to the top

			mov 	word ptr [VidPtr],di

			pop 	di
			pop 	es
            jmp     overit

		;
		prtit:
		;
		; convert one nibble to a hex 0-F
		;
			add 	al,90h
			daa
			adc 	al,0
			add 	al,40h
			daa
		;
		int1014:
			cld
			stosw
			ret
		;
		overit:
	}
}


;	/*\
;---|*| End of MIDI.C
;	\*/

