[net.micro.atari16] Need MIDI port info for 520ST

sansom@trwrba.UUCP (04/22/86)

In article <9000001@ima> peterb@ima writes:
>
>Help... I bought my 520ST to use to drive my MIDI keyboards, and don't find
>any documentation on how to access them. And since I understand assembler,
>could some kind soul give me a quick hack of a routine that can read and write
>to the MIDI ports. Also if there is any other documentation on them, please
>point me to it. It would be nice to get some C code to go with the stubs...
>

The following program will give a rudimentary introduction to the ST's
MIDI capabilities.  I pulled this from the net a couple of months ago.

Richard E. Sansom
TRW Electronics & Defense Sector
{...decvax,ucbvax,ihnp4}!trwrb!trwrba!sansom

--------------------------------------------------------------------------
/* mr.c */
/* Nigel Roles 1986 */

#include "osbind.h"

#define MIDI 3
#define CON 2
#define GM (Bconin(MIDI)&0xff)

struct event {
	int delay;
	char cmd[3];
};

struct event *buffer;

int empty=1;
long bc;
long memsize;
long bmax;

long hz200()
{
	register long save_ssp=Super(0L);
	register long uhz200= *(long *)0x4ba;
	Super(save_ssp);
	return uhz200;
}

record()
{
	register struct event *bp;
	long now,then;
	printf("Recording (any key to stop):\n");
	while (Bconstat(MIDI))
		Bconin(MIDI);
	then=0;
	bp=buffer;
	bc=0;
	for (;;) {
		if (Bconstat(CON)) {
			Bconin(CON);
			bp->delay= -1;
			bc++;
			break;
		}
		if (Bconstat(MIDI)) {
			int b=GM;
			if (b==0xfe)
				continue;	/* Ignore active sensing */
			if (b==0x90) {
				now=hz200();
				if (then==0)
					bp->delay=0;
				else
					bp->delay=now-then;
				then=now;
				bp->cmd[0]=b;
				bp->cmd[1]=GM;
				bp++->cmd[2]=GM;
				if (++bc==bmax) {
					printf("Buffer full\n");
					break;
				}
			}
		}
	}
}

play()
{
	register struct event *bp=buffer;
	long target;
	printf("Playing:\n");
	while (bp->delay!= -1) {
		if (Bconstat(CON)) {
			Bconin(CON);
			break;
		}
		target=hz200()+bp->delay;
		while (hz200()<target) ;
		Midiws(2,bp->cmd);
		bp++;
	}
}

#define FNSIZE 20
struct filename {
	char lin,lout;
	char name[FNSIZE+1];
} fn;

int h;

getfn()
{
	printf("Filename: ");
	fn.lin=FNSIZE;
	Cconrs((char *)&fn);
	printf("\n");
	fn.name[fn.lout]='\0';
}

load()
{
	getfn();
	if ((h=Fopen(fn.name,0))<0) {
		printf("Can't open %s for reading (error %d)\n",fn.name,h);
		return;
	}
	if (Fread(h,memsize,buffer)<0)
		printf("Read error\n");
	else
		empty=0;
	Fclose(h);
}
		
save()
{
	getfn();
	Fdelete(fn.name);
	if ((h=Fcreate(fn.name,0))<0) {
		printf("Can't create %s (error %d)\n",fn.name,h);
		return;
	}
	if (Fwrite(h,sizeof(struct event)*(long)bc,buffer)<0)
		printf("Write error\n");
	Fclose(h);
}
		
main()
{
	char c;
	char *malloc();
	memsize=(long)malloc(-1L);
	if ((buffer=(struct event *)malloc(memsize))==(struct event *)0L) {
		printf("malloc failure\n");
		exit(1);
	}
	bmax=memsize/sizeof(struct event);
	printf("\033EMidi Recorder Version 1.0 (definitely)\n");
	printf("(C) N. G. Roles 1985\n\n");
	printf("Capacity: %D events\n",bmax);
	for (;;) {
		printf("MR> ");
		c=Bconin(CON);
		printf("%c\n",c);
		switch (c) {
		case 'q':
			break;
		case 'r':
			record();
			continue;
		case 'p':
			if (empty)
				printf("Nothing to play!\n");
			else
				play();
			continue;
		case 's':
			if (empty)
				printf("Nothing to save!\n");
			else
				save();
			continue;
		case 'l':
			load();
			continue;
		default:
			printf("???\n");
			continue;
		}
		break;
	}
}
-- 
Richard E. Sansom
TRW Electronics & Defense Sector
{...decvax,ucbvax,ihnp4}!trwrb!trwrba!sansom