home *** CD-ROM | disk | FTP | other *** search
/ Mega CD-ROM 1 / megacd_rom_1.zip / megacd_rom_1 / MUSIC / POLYTC.ZIP / POLY_PLA.C < prev    next >
C/C++ Source or Header  |  1987-12-31  |  5KB  |  171 lines

  1. /*
  2.  *    poly_play - Play a polyphonic tune.
  3.  */
  4. #include <stdio.h>
  5.  
  6. #define TRUE    (1)
  7. #define FALSE    (0)
  8.  
  9. int tune[5000];
  10. char name[80];
  11. FILE *tfp;
  12.  
  13. int *tunep;
  14. int tempo;
  15. int duration;
  16.  
  17. main( argc, argv )
  18. int argc;
  19. char *argv[];
  20. {
  21.     int tindex;
  22.  
  23.     if( argc != 2 )
  24.     {
  25.         tfprintf( stderr, "\nUsage: poly_play tunefile\n\n");
  26.         exit( 1 );
  27.     }
  28.  
  29.     if( !(tfp = fopen(argv[1], "r")) )
  30.     {
  31.         tfprintf( stderr, "\n*** Unable to open tune file ***\n" );
  32.         exit( 2 );
  33.     }
  34.  
  35.     fgets( name, 80, tfp );
  36.     tindex = 0;
  37.  
  38.     while( tfscanf(tfp, "%d", &tune[tindex++]) != -1)
  39.         ;
  40.  
  41.     fclose( tfp );
  42.  
  43.     tunep = tune;                        /* Initialize tune pointer */
  44.     tempo = 0x1fff;                        /* Set up default tempo */
  45. /*
  46.  *  Now attempt to play the tune...
  47.  */
  48.     asm( "push ax" );                    /* Save registers */
  49.     asm( "push bx" );
  50.     asm( "push cx" );
  51.     asm( "push dx" );
  52.     asm( "push si" );
  53.     asm( "push di" );
  54.     asm( "push bp" );
  55.     asm( "push es" );
  56.     asm( "push <tempo>" );                /* Initialize tempo counter */
  57.     asm( "xor ax,ax" );                    /* Must write 0 into voice count and */
  58.     asm( "mov bx,ax" );                    /*  data registers */
  59.     asm( "mov dx,ax" );
  60.     asm( "mov si,ax" );
  61.     asm( "mov bp,ax" );
  62.     asm( "mov di,ax" );
  63.     asm( "mov es,ax" );
  64.     asm( "mov cx,#12h" );                /* Initialize shift value */
  65. /*
  66.  *  This section sorts the tune data into the appropriate registers
  67.  *  Voice period data is stored in ES for voice 1, DI for voice 2,
  68.  *  and SI for voice 3.  The voice period count is stored in BX for
  69.  *  voice 1, DX for voice 2, and BP for voice 3.
  70.  */
  71.     asm( "sort:" );
  72.         asm( "push bx" );
  73.         asm( "push dx" );
  74.     asm( "sort_1:" );
  75.         asm( "add <tunep>,#2" );
  76.         asm( "mov bx,<tunep>" );        /* Get tune pointer */
  77.         asm( "mov ax,[bx]" );            /* Get tune data in AX */
  78.         asm( "mov dx,ax" );                /* Make a copy in DX */
  79.         asm( "and dx,#1FFFh" );            /* Strip off 3 data type bits */
  80.         asm( "shl ax" );                /* Move msb into carry bit */
  81.         asm( "jnc sort_4" );            /* Jump if end, duration, or tempo data */
  82.         asm( "shl ax" );                /* Move 2nd msb into carry bit */
  83.         asm( "jc sort_3" );                /* Jump if voice 3 data */
  84.         asm( "shl ax" );                /* Move 3rd msb into carry bit */
  85.         asm( "jc sort_2" );                /* Jump if voice 2 data */
  86.         asm( "mov es,dx" );                /* Store voice 1 data in ES */
  87.         asm( "jmp sort_1" );
  88.     asm( "sort_2:" );
  89.         asm( "mov di,dx" );                /* Store voice 2 data in DI */
  90.         asm( "jmp sort_1" );
  91.     asm( "sort_3:" );
  92.         asm( "mov si,dx" );                /* Store voice 3 data in SI */
  93.         asm( "jmp sort_1" );            /* Ignore */
  94.     asm( "sort_4:" );
  95.         asm( "shl ax" );                /* Move 2nd msb into carry bit */
  96.         asm( "jnc sort_6" );            /* Jump if end or duration data */
  97.         asm( "shl ax" );
  98.         asm( "jnc sort_5" );            /* Jump if tempo data */
  99.         asm( "jmp sort_1" );            /* Ignore */
  100.     asm( "sort_5:" );
  101.         asm( "mov <tempo>,dx" );        /* Store tempo */
  102.         asm( "pop dx" );                /* Restore registers */
  103.         asm( "pop bx" );
  104.         asm( "pop ax" );                /* Burn the current tempo counter */
  105.         asm( "push <tempo>" );            /*  and put in the new one */
  106.         asm( "push bx" );                /* Save registers again */
  107.         asm( "push dx" );
  108.         asm( "jmp sort_1" );
  109.     asm( "sort_6:" );
  110.         asm( "shl ax" );                /* Move 3rd msb into carry */
  111.         asm( "jc sort_7" );                /* Jump if duration */
  112.         asm( "pop dx" );
  113.         asm( "pop bx" );
  114.         asm( "pop ax" );                /* Get rid or tempo counter */
  115.         asm( "jmp theend" );
  116.     asm( "sort_7:" );
  117.         asm( "mov <duration>,dx" );        /* Store duration data */
  118.         asm( "pop dx" );
  119.         asm( "pop bx" );
  120.     asm( "theloop:" );
  121.         asm( "cli" );                    /* Turn off interrupts during note */
  122.         asm( "pop ax" );                /* Get tempo counter */
  123.         asm( "dec ax" );                /* Decrement it */
  124.         asm( "push ax" );                /* Put it back */
  125.         asm( "jnz play" );                /* Jump if some tempo remains */
  126.         asm( "pop ax" );                /* Get tempo counter */
  127.         asm( "mov ax,<tempo>" );        /* Reset tempo counter */
  128.         asm( "push ax" );                /*  and put it back */
  129.         asm( "dec <duration>" );        /* Decrement duration counter */
  130.         asm( "jnz play" );                /* Continue if not finished */
  131.         asm( "sti" );                    /* Turn interrupts back on */
  132.         asm( "jmp sort" );                /* Get new tune data if duration up */
  133. /*
  134.  *  This routine plays the notes until the duration counter
  135.  *  reaches zero.  At that time, the new data is sorted.
  136.  */
  137.     asm( "play:" );
  138.         asm( "add bx,si" );                /* Add voice 3 data to count */
  139.         asm( "rol bx" );                /* Get msb of voice 3 count */
  140.         asm( "mov ax,cx" );                /* Keeps keyboard clk on and */
  141.         asm( "rcl al" );                /*  casette motor relay off */
  142.         asm( "rcl al" );
  143.         asm( "b out 061h" );
  144.         asm( "ror bx" );                /* Restore bx to original state */
  145.         asm( "add dx,di" );                /* Add voice 2 data to count */
  146.         asm( "rol dx" );
  147.         asm( "mov ax,cx" );
  148.         asm( "rcl al" );
  149.         asm( "rcl al" );
  150.         asm( "b out 061h" );
  151.         asm( "ror dx" );
  152.         asm( "mov ax,es" );
  153.         asm( "add bp,ax" );                /* Add voice 1 data to count */
  154.         asm( "rol bp" );
  155.         asm( "mov ax,cx" );
  156.         asm( "rcl al" );
  157.         asm( "rcl al" );
  158.         asm( "b out 061h" );
  159.         asm( "ror bp" );
  160.         asm( "jmp theloop" );
  161.     asm( "theend:" );
  162.         asm( "pop es" );                /* Restore registers */
  163.         asm( "pop bp" );
  164.         asm( "pop di" );
  165.         asm( "pop si" );
  166.         asm( "pop dx" );
  167.         asm( "pop cx" );
  168.         asm( "pop bx" );
  169.         asm( "pop ax" );
  170. }
  171.