home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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;
- }
-