🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: net.micro.atari
Article #2023

Re: ST timer tick? (includes FREE Midi Recorder program)

#2023
From: nigel
Date: Sun, 12 Jan 1986 15:04
197 lines
4723 bytes
In article <1241@gitpyr.UUCP> tynor@gitpyr.UUCP (Steve Tynor) writes:
>Can anyone tell me how I can get a simple timer tick on my ST?  I need a
>high resolution timer so that I can record keystrokes off of MIDI for a 
>simple sequencer I'm writing.  However, I've looked through all the
>developer documentation and can't figure out how to do it...  Do I have to
>write an interupt handler to count timer interupts? (ugh...) I can't believe
>it's as hard as that...
>
You're right - it's not difficult.

I have done this myself, so rather than just reply with the appropriate
routine, I draw attention to the routine hz200() in the following program.
It is a MIDI recorder - it listens to what is being played, can store it on
disk, and play it back. I hacked it together in an afternoon, so it's not
earth-shattering stuff. It only listens on one channel, and ignores all
but note information. It does preserve velocity information, and was tested
on a Yamaha DX7. If anyone does improve this, I would appreciate seeing the
source code.

PS - can anyone spot the deliberate mistake?

--------------------------------------------------------------------------
/* 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;
	}
}
Technical Details
Message-ID: <651@minster.UUCP>
Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!burl!ulysses!gamma!epsilon!zeta!sabre!petrus!bellcore!decvax!genrad!panda!talcott!harvard!seismo!mcvax!ukc!reading!minster!nigel
References: <1241@gitpyr.UUCP>

Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10 5/3/83; site minster.UUCP
Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!burl!ulysses!gamma!epsilon!zeta!sabre!petrus!bellcore!decvax!genrad!panda!talcott!harvard!seismo!mcvax!ukc!reading!minster!nigel
From: nigel@minster.UUCP (nigel)
Newsgroups: net.micro.atari
Subject: Re: ST timer tick? (includes FREE Midi Recorder program)
Message-ID: <651@minster.UUCP>
Date: Sun, 12-Jan-86 10:04:18 EST
Article-I.D.: minster.651
Posted: Sun Jan 12 10:04:18 1986
Date-Received: Tue, 14-Jan-86 06:16:03 EST
References: <1241@gitpyr.UUCP>
Reply-To: nigel@minster.UUCP (nigel)
Organization: University of York, England
Lines: 197
Xpath: ukc eagle