Metropoli BBS
VIEWER: gustest.c MODE: TEXT (ASCII)
/*

  GUSTEST.C --- example program using GUS C routine library

  Michael Chen
  mchen@cs.psu.edu
  4/18/1993

  See the included .TXT file for terms and other information.

*/

#include "gus.h"
#include <stdio.h>
#include <conio.h>
#include <string.h>

void PlaySampleFile(char* buf, int SampleBits, unsigned int pfreq, int sgnd,
                    int SwapBytes)
    {
    FILE* File;
    longword bytes;
    longword inc;
    byte* dbuf;
    char fn[128];

    byte mode, vc;
    longword sstart, pos, lstart, lend;
    word freq;
    word vol;

    strcpy(fn,buf);
    if (strchr(fn,'.') == NULL)
      strcat(fn,".SAM");

    File = fopen(fn,"rb");
    if (File == NULL)
      {
      printf("Error opening sample file %s.\n",buf);
      exit(3);
      }

    /* Load sample into GUS memory. */

    for (bytes = 16384; bytes > 0; bytes >>= 1)
      {
      dbuf = (byte*) calloc(sizeof(byte),bytes);
      if (dbuf != NULL) break;
      }
    if (bytes)
      {
      printf("Allocated %ld bytes for data buffer.\n",bytes);
      }
    else
      {
      printf("Unable to allocate data buffer.\n");
      exit(4);
      }

    sstart = 0x0;
    pos = sstart;

    if (sgnd)
      printf("Converting unsigned data.\n");

    if ((SwapBytes) && (SampleBits > 8))
      printf("Swapping data bytes.\n");

    while (!feof(File))
      {
      bytes = fread(dbuf,sizeof(byte),bytes,File);

      if ((SwapBytes) && (SampleBits > 8))
        swab(dbuf,dbuf,bytes);

      /* Convert for signed */
      if (sgnd)
        {
        for (inc = 0; inc < bytes; inc++)
          {
          if (SampleBits > 8) inc++;
          dbuf[inc] ^= 0x80;
          }
        }

      /* Write to GUS DRAM */
      GUSSetDRAM(pos,dbuf,bytes);

      pos += bytes;
      if (bytes)
        {
        printf("\rRead %ld bytes from sample file %s (%ld total).",
               bytes,buf,pos);
        }
      else
        {
        printf("\rError reading from sample file %s.      \n",buf);
        exit(5);
        }
      }
    pos--;

    printf("\r%79s\rDone loading sample data into GUS DRAM (%ld total).\n",
           "",pos-sstart+1);

    free(dbuf);
    if (fclose(File))
      {
      printf("Error closing sample file %s.\n",buf);;
      exit(7);
      }

    /* Sample goes from sstart to pos. */

    GUSStopVoice(0);
    GUSStopRamp(0);
    if (SampleBits == 8)
      {
      GUSSetVoiceMode(0,V_8Bit|V_Loop|V_Unidirectional|V_Forward);
      GUSSetVolumeControl(0,V_Loop|V_Unidirectional|V_StopRamp);
      GUSSetLoopEnd(0,pos);
      }
    else
      {
      GUSSetVoiceMode(0,V_16Bit|V_Loop|V_Unidirectional|V_Forward);
      GUSSetVolumeControl(0,V_Loop|V_Unidirectional|V_StopRamp);
      GUSSetLoopEnd(0,pos/2);
      }
    GUSSetLoopStart(0,sstart);
    GUSSetPosition(0,sstart);
    GUSSetVoices(MINVOICES);
    GUSSetVoiceFreq(0,pfreq);

    /* Should be ready... play until key pressed. */

    printf("Now playing sample file %s; press any key to stop.\n",buf);
    GUSSetVolume(0,0xF800);
    GUSStartVoice(0);

    while (!kbhit())
      {
      delay(100);
      mode = GUSReadVoiceMode(0);
      pos = GUSReadPosition(0);
      lstart = GUSReadLoopStart(0);
      lend = GUSReadLoopEnd(0);
      freq = GUSReadVoiceFreq(0);
      vol = GUSReadVolume(0);
      vc = GUSReadVolumeControl(0);

      printf(
"pos 0x%05lx lst 0x%05lx end 0x%05lx frq %5ud vl 0x%04x vlc 0x%02x md 0x%02x\r",
        pos,lstart,lend,freq,vol,vc,mode);
      }
    getch();
    printf("\n");

    GUSStopVoice(0);
    printf("Done playing sample file %s.\n",buf);
    }

void TestGUSDRAM(longword dram)
    {
    longword ul, inc;
    word base;

    printf("Testing DRAM.\n");

    inc = 1;
    for (ul=0; ul < dram; ul += inc)
      {
      if (!(ul & 0xFFF))
        printf("%05lx\r",ul);
      for (base=0xF; base < 0x100; base <<= 4)
        {
        if (GUSPokePeek(ul,base) != base)
          break;
        }
      if (base < 0x100)
        break;
      }

    if (ul != dram)
      {
      printf("Memory error at %ld (0x%05lx).\n",ul,ul);
      exit(2);
      }
    else
      {
      printf("Memory tests OK.\n");
      }
    }

void ZeroGUSDRAM(longword dram)
    {
    longword ul;

    printf("Clearing DRAM.\n");

/*
    for (ul=0; ul < dram; ul ++)
      {
      if (GUSPokePeek(ul,0))
        break;
      }
*/

    GUSFillDRAM(0,0,dram);
    ul = dram;

    if (ul != dram)
      {
      printf("Memory error at %ld (0x%05lx).\n",ul,ul);
      exit(2);
      }
    else
      {
      printf("Memory cleared OK.\n");
      }
    }

void DumpGUSDRAM(longword dram)
    {
    longword ul;
    int i;

    printf("Dumping DRAM.\n");

    for (ul=0; (ul < dram) && (!kbhit()); ul += 24)
      {
      printf("%5lx:",ul);
      for (i=0; i < 24; i++)
        printf(" %2x",GUSPeek(ul+i));
      printf("\n");
      if ((ul/24+1) % 24 == 0)
        {
        getch();
        }
      }

    if (ul != dram)
      {
      printf("Dump stopped at %ld (0x%05lx).\n",ul,ul);
      exit(2);
      }
    else
      {
      printf("Dump OK.\n");
      }
    }

void main(int argc, char* argv[])
  {
  #define MAXARGS       16

  int base;
  longword inc;
  longword ul;
  longword dram;
  longword bytes;
  byte* dbuf;
  byte buf[128];
  byte b;
  word w;
  FILE* File;
  char *argps[MAXARGS];
  int args = 0;

  long int OptionSet;
  unsigned int VoiceFreq = 22000;
  int DefaultOption = 1;
  int TestDRAM = 0;
  int PlaySample = 0;
  int SampleBits = 8;
  int ShowPorts = 0;
  int ZeroDRAM = 0;
  int DumpDRAM = 0;
  int Unsigned = 0;
  int SwapBytes = 0;

  printf("\nGUS Tester v1.22 by Michael Chen 4/18/1993\n");

  /* Process options */

  for (base = 1; base < argc; base++)
    {
    if ((*argv[base] == '-') || (*argv[base] == '/'))
      {
      switch (argv[base][2])
        {
        case '+':       OptionSet = 1; break;
        case '-':       OptionSet = 0; break;
        case 0:         OptionSet = DefaultOption; break;
        default:        OptionSet = atol(&argv[base][2]);
        }
      switch (argv[base][1])
        {
        case 't':       TestDRAM = OptionSet; break;
        case 'f':       VoiceFreq = OptionSet; break;
        case 'z':       ZeroDRAM = OptionSet; break;
        case 'd':       DumpDRAM = OptionSet; break;
        case 'u':       Unsigned = OptionSet; break;
        case 's':       Unsigned = !OptionSet; break;
        case 'w':       SwapBytes = OptionSet; break;
        case 'p':       ShowPorts = OptionSet; break;
        case 'b':       if ((OptionSet != 8) && (OptionSet != 16))
                          {
                          printf("Sample bits must be 8 or 16\n");
                          }
                        else
                          SampleBits = OptionSet;
                        break;
        default:        printf("Invalid argument %s\n",argv[base]);
                        exit(1);
        }
      }
    else
      {
      argps[args++] = argv[base];
      PlaySample = 1;
      }
    }

  /* Check to see where GUS is installed. */

  base = DetectGUS();
  if (!base)
    {
    printf("GUS not detected!\n");
    exit(1);
    }

  printf("GUS detected at base address 0x%03x.\n",base);

  GUSReset();

  if (ShowPorts)
    {
    printf("%-24s (0x%02x): %d\n",
      "GUS mixer control",GUSMixer,GUSReadMixer());
    printf("%-24s (0x%02x): %d\n",
      "GUS status",GUSStatus,inportb(GUSStatus));
    printf("%-24s (0x%02x): %d\n",
      "GUS timer control",GUSTimerControl,inportb(GUSTimerControl));
    printf("%-24s (0x%02x): %d\n",
      "GUS timer data",GUSTimerData,inportb(GUSTimerData));
    printf("%-24s (0x%02x): %d\n",
      "GUS IRQ/DMA control",GUSIRQDMAControl,inportb(GUSIRQDMAControl));
    printf("%-24s (0x%02x): %d\n",
      "GUS MIDI control",GUSMIDIControl,inportb(GUSMIDIControl));
    printf("%-24s (0x%02x): %d\n",
      "GUS MIDI data",GUSMIDIData,inportb(GUSMIDIData));
    }

  /* Check to see how much RAM is there */

  inc = 0x40000;
  for (dram = 0; dram < 0x100000; dram += inc)
    {
    printf("\rChecking GUS DRAM at %05lx.",dram);
    for (base = 0; base < 0x100; base++)
      {
      if (GUSPokePeek(dram,base) != base)
        break;
      }
    if (base < 0x100)
      break;
    }

  printf("\r%ld Kbytes of DRAM installed.            \n",dram/1024);

  if (TestDRAM)
    {
    TestGUSDRAM(dram);
    }

  if (PlaySample)
    {
    if (args)
      for (base = 0; base < args; base++)
        PlaySampleFile(argps[base],SampleBits,VoiceFreq,Unsigned,SwapBytes);
    }

  if (ZeroDRAM)
    {
    ZeroGUSDRAM(dram);
    }

  if (DumpDRAM)
    {
    DumpGUSDRAM(dram);
    }
  }

[ RETURN TO DIRECTORY ]