home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Audio 4.94 - Over 11,000 Files
/
audio-11000.iso
/
msdos
/
music
/
polytc
/
poly_pla.tc
< prev
next >
Wrap
Text File
|
1991-05-25
|
5KB
|
171 lines
/*
* poly_play - Play a polyphonic tune.
*/
#include <stdio.h>
#define TRUE (1)
#define FALSE (0)
int tune[5000];
char name[80];
FILE *tfp;
int *tunep;
int tempo;
int duration;
main( argc, argv )
int argc;
char *argv[];
{
int tindex;
if( argc != 2 )
{
fprintf( stderr, "\nUsage: poly_play tunefile\n\n");
exit( 1 );
}
if( !(tfp = fopen(argv[1], "r")) )
{
fprintf( stderr, "\n*** Unable to open tune file ***\n" );
exit( 2 );
}
fgets( name, 80, tfp );
tindex = 0;
while( fscanf(tfp, "%d", &tune[tindex++]) != -1)
;
fclose( tfp );
tunep = tune; /* Initialize tune pointer */
tempo = 0x1fff; /* Set up default tempo */
/*
* Now attempt to play the tune...
*/
asm push ax; /* Save registers */
asm push bx;
asm push cx;
asm push dx;
asm push si;
asm push di;
asm push bp;
asm push es;
asm push tempo; /* Initialize tempo counter */
asm xor ax,ax; /* Must write 0 into voice count and */
asm mov bx,ax; /* data registers */
asm mov dx,ax;
asm mov si,ax;
asm mov bp,ax;
asm mov di,ax;
asm mov es,ax;
asm mov cx,12h; /* Initialize shift value */
/*
* This section sorts the tune data into the appropriate registers
* Voice period data is stored in ES for voice 1, DI for voice 2,
* and SI for voice 3. The voice period count is stored in BX for
* voice 1, DX for voice 2, and BP for voice 3.
*/
sort:;
asm push bx;
asm push dx;
sort_1:;
asm add tunep,2;
asm mov bx,tunep; /* Get tune pointer */
asm mov ax,[bx]; /* Get tune data in AX */
asm mov dx,ax; /* Make a copy in DX */
asm and dx,1FFFh; /* Strip off 3 data type bits */
asm shl ax,1; /* Move msb into carry bit */
asm jnc sort_4; /* Jump if end, duration, or tempo data */
asm shl ax,1; /* Move 2nd msb into carry bit */
asm jc sort_3; /* Jump if voice 3 data */
asm shl ax,1; /* Move 3rd msb into carry bit */
asm jc sort_2; /* Jump if voice 2 data */
asm mov es,dx; /* Store voice 1 data in ES */
asm jmp sort_1;
sort_2:;
asm mov di,dx; /* Store voice 2 data in DI */
asm jmp sort_1;
sort_3:;
asm mov si,dx; /* Store voice 3 data in SI */
asm jmp sort_1; /* Ignore */
sort_4:;
asm shl ax,1; /* Move 2nd msb into carry bit */
asm jnc sort_6; /* Jump if end or duration data */
asm shl ax,1;
asm jnc sort_5; /* Jump if tempo data */
asm jmp sort_1; /* Ignore */
sort_5:;
asm mov tempo,dx; /* Store tempo */
asm pop dx; /* Restore registers */
asm pop bx;
asm pop ax; /* Burn the current tempo counter */
asm push tempo; /* and put in the new one */
asm push bx; /* Save registers again */
asm push dx;
asm jmp sort_1;
sort_6:;
asm shl ax,1; /* Move 3rd msb into carry */
asm jc sort_7; /* Jump if duration */
asm pop dx;
asm pop bx;
asm pop ax; /* Get rid or tempo counter */
asm jmp theend;
sort_7:;
asm mov duration,dx; /* Store duration data */
asm pop dx;
asm pop bx;
theloop:;
asm cli; /* Turn off interrupts during note */
asm pop ax; /* Get tempo counter */
asm dec ax; /* Decrement it */
asm push ax; /* Put it back */
asm jnz play; /* Jump if some tempo remains */
asm pop ax; /* Get tempo counter */
asm mov ax,tempo; /* Reset tempo counter */
asm push ax; /* and put it back */
asm dec duration; /* Decrement duration counter */
asm jnz play; /* Continue if not finished */
asm sti; /* Turn interrupts back on */
asm jmp sort; /* Get new tune data if duration up */
/*
* This routine plays the notes until the duration counter
* reaches zero. At that time, the new data is sorted.
*/
play:;
asm add bx,si; /* Add voice 3 data to count */
asm rol bx,1; /* Get msb of voice 3 count */
asm mov ax,cx; /* Keeps keyboard clk on and */
asm rcl al,1; /* casette motor relay off */
asm rcl al,1;
asm out 061h, al;
asm ror bx,1; /* Restore bx to original state */
asm add dx,di; /* Add voice 2 data to count */
asm rol dx,1;
asm mov ax,cx;
asm rcl al,1;
asm rcl al,1;
asm out 061h, al;
asm ror dx,1;
asm mov ax,es;
asm add bp,ax; /* Add voice 1 data to count */
asm rol bp,1;
asm mov ax,cx;
asm rcl al,1;
asm rcl al,1;
asm out 061h, al;
asm ror bp,1;
asm jmp theloop;
theend:;
asm pop es; /* Restore registers */
asm pop bp;
asm pop di;
asm pop si;
asm pop dx;
asm pop cx;
asm pop bx;
asm pop ax;
}