Annotation of uae/src/md-i386-dos/sound/gus.c, revision 1.1.1.1

1.1       root        1:  /*
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   *
                      4:   * DOS Gravis Ultrasound interface.
                      5:   *
                      6:   * Version 0.2
                      7:   *
                      8:   * (c) 1996 Michael Sontheimer
                      9:   *
                     10:   * Please, do not change the code ! Write a email to me with the bugfix,
                     11:   * the improvement or the suggestion. My email: [email protected]
                     12:   *
                     13:   */
                     14: 
                     15: 
                     16: //#define DEBUG
                     17: 
                     18: #include <stdlib.h>
                     19: #include <stdio.h>
                     20: #include <string.h>
                     21: #include <ctype.h>
                     22: #include <dos.h>
                     23: #include <pc.h>
                     24: #include <sys/farptr.h>
                     25: #include <dpmi.h>
                     26: #include <go32.h>
                     27: 
                     28: 
                     29: #include "sysconfig.h"
                     30: #include "sysdeps.h"
                     31: #include "sound/gus.h"
                     32: #include "sound/dma.h"
                     33: 
                     34: 
                     35: 
                     36: #ifndef TRUE
                     37: #define TRUE 1
                     38: #endif
                     39: #ifndef FALSE
                     40: #define FALSE 0
                     41: #endif
                     42: 
                     43: 
                     44: // GUS Ports
                     45: 
                     46: #define GUS_COMMAND   0x103
                     47: #define GUS_DATAHI    0x105
                     48: #define GUS_DATALO    0x104
                     49: #define GUS_IRQSTATE  0x006
                     50: #define GUS_TIMERCTRL 0x008
                     51: #define GUS_TIMERDATA 0x009
                     52: #define GUS_VOICE     0x102
                     53: #define GUS_DRAM      0x107
                     54: #define GUS_MIXER     0x000
                     55: #define GUS_DMACTRL   0x00b     // Beide Adressen sind identisch !!!
                     56: #define GUS_IRQCTRL   0x00b
                     57: #define GUS_REGISTERCTRL 0x00f
                     58: 
                     59: // GUS Kommandos
                     60: 
                     61: #define GUS_CMD_RESET       0x4c
                     62: #define GUS_CMD_DRAMDMACTRL 0x41
                     63: #define GUS_CMD_DMASTARTADR 0x42
                     64: #define GUS_CMD_DRAMIOADRLO 0x43
                     65: #define GUS_CMD_DRAMIOADRHI 0x44
                     66: #define GUS_CMD_TIMERCTRL   0x45
                     67: #define GUS_CMD_COUNTER1    0x46
                     68: #define GUS_CMD_COUNTER2    0x47
                     69: #define GUS_CMD_SAMPLEFREQ  0x48
                     70: #define GUS_CMD_SAMPLECTRL  0x49
                     71: 
                     72: #define GUS_CMD_VOICECTRLW  0x00
                     73: #define GUS_CMD_FREQUCTRLW  0x01
                     74: #define GUS_CMD_STARTHIW    0x02
                     75: #define GUS_CMD_STARTLOW    0x03
                     76: #define GUS_CMD_ENDHIW      0x04
                     77: #define GUS_CMD_ENDLOW      0x05
                     78: #define GUS_CMD_RAMPRATEW   0x06
                     79: #define GUS_CMD_VOLUMEW     0x09
                     80: #define GUS_CMD_CURRENTHIW  0x0a
                     81: #define GUS_CMD_CURRENTLOW  0x0b
                     82: #define GUS_CMD_PANPOSW     0x0c
                     83: #define GUS_CMD_VOLUMECTRLW 0x0d
                     84: #define GUS_CMD_ACTIVEVOICESW 0x0e
                     85: 
                     86: #define GUS_CMD_VOICECTRLR  0x80
                     87: #define GUS_CMD_FREQUCTRLR  0x81
                     88: #define GUS_CMD_STARTHIR    0x82
                     89: #define GUS_CMD_STARTLOR    0x83
                     90: #define GUS_CMD_ENDHIR      0x84
                     91: #define GUS_CMD_ENDLOR      0x85
                     92: #define GUS_CMD_VOLUMER     0x89
                     93: #define GUS_CMD_CURRENTHIR  0x8a
                     94: #define GUS_CMD_CURRENTLOR  0x8b
                     95: #define GUS_CMD_PANPOSR     0x8c
                     96: #define GUS_CMD_VOLUMECTRLR 0x8d
                     97: #define GUS_CMD_ACTIVEVOICESR 0x8e
                     98: #define GUS_CMD_IRQSOURCER  0x8f
                     99: 
                    100: #define ADDR_HI(x) ((UWORD)((((ULONG)(x))>>7L)&0x1fffL))
                    101: #define ADDR_LO(x)  ((UWORD)((((ULONG)(x))&0x7fL)<<9L))
                    102: 
                    103: 
                    104: #define LSW( x ) ((UWORD)(((ULONG)(x))&0xffffL))
                    105: #define MSW( x ) ((UWORD)(((ULONG)(x))>>16L))
                    106: #define LSB( x ) ((UBYTE)(((UWORD)(x))&0xffL))
                    107: #define MSB( x ) ((UBYTE)(((UWORD)(x))>>8))
                    108: #define CONVTO16B( x ) ((((x)>>1L)&0x0001ffffL)|((x)&0x000c0000L))
                    109: #define NUMPARAS(bytesize) (((bytesize)+15) >> 4)
                    110: 
                    111: 
                    112: 
                    113: // Variablen
                    114: 
                    115: 
                    116: UWORD uwGUSPort;
                    117: UBYTE ubGUSGF1Int;
                    118: UBYTE ubGUSMIDIInt;
                    119: UBYTE ubGUSDMA1;
                    120: UBYTE ubGUSDMA2;
                    121: UBYTE ubGUSUsedBits;           // 0 if 8 bit or 4 if 16 bit
                    122: UWORD uwGUSUsedFreq;
                    123: UBYTE ubGUSGF1IRQVector;       // Physikalischer Vektor des GF1 IRQ's
                    124: UBYTE *pGUSBuffer;             // Zwischenpuffer
                    125: ULONG nGUSBufferWriteIndex;
                    126: ULONG nGUSBufferReadIndex;
                    127: ULONG ulBytesInBuffer;          // Anzahl der Bytes im Puffer
                    128: ULONG ulGUSSndBufSize;
                    129: ULONG ulDMABufMaxSize;
                    130: ULONG ulFragSize;               // Elementgroesse, die ich haben will
                    131: 
                    132: int bIgnoreGF1IRQ=TRUE;
                    133: int bDMAInProgress=FALSE;
                    134: int bVoicesFast=FALSE;          // Wird schneller abgespielt als normal ?
                    135: 
                    136: 
                    137: _go32_dpmi_seginfo   old_pmintGF1;  /* the old interrupt handler         */
                    138: _go32_dpmi_seginfo   pm_wrapperGF1; /* the new interrupt handler         */
                    139: 
                    140: UBYTE ubDummy;
                    141: 
                    142: static __inline__ void WriteGUSb( UWORD uwReg, UBYTE ubByte )
                    143: {
                    144:        outportb( uwGUSPort+uwReg, ubByte );
                    145: }
                    146: 
                    147: static __inline__ UBYTE ReadGUSb( UWORD uwReg )
                    148: {
                    149:        return inportb( uwGUSPort+uwReg );
                    150: }
                    151: 
                    152: static __inline__ void WriteGUSw( UWORD uwReg, UWORD uwWord )
                    153: {
                    154:        outportw( uwGUSPort+uwReg, uwWord );
                    155: }
                    156: 
                    157: static __inline__ UWORD ReadGUSw( UWORD uwReg )
                    158: {
                    159:        return inportw( uwGUSPort+uwReg );
                    160: }
                    161: 
                    162: 
                    163: _go32_dpmi_seginfo  dma_mem;            // Zeiger auf DMA-Speicher
                    164: ULONG dmabufadr;
                    165: 
                    166: void GUS_GF1Delay( void )
                    167: {
                    168: 
                    169:     int i;
                    170: 
                    171:     for( i=0; i<6; i++ )
                    172:         inportb( uwGUSPort+GUS_DATAHI );
                    173: 
                    174: 
                    175: }
                    176: 
                    177: /*******************************
                    178: 
                    179: void GUS_Reset( UBYTE ubGUSDMA1, UBYTE ubGUSDMA2, ubGUSGF1Int )
                    180: 
                    181: *******************************/
                    182: 
                    183: void GUS_Reset( UBYTE ubGUSDMA1, UBYTE ubGUSDMA2, UBYTE ubGUSGF1Int  )
                    184: {
                    185:     int i, j;
                    186:     UBYTE nDMA, nInt;
                    187: 
                    188:     WriteGUSb( GUS_MIXER, 1|2 );  // Latches aus, Alle Aus/Eingaben aus
                    189: 
                    190:     // Reset
                    191:     WriteGUSb( GUS_COMMAND, GUS_CMD_RESET );
                    192:     WriteGUSb( GUS_DATAHI, 0 );
                    193:     delay( 100 );
                    194:     WriteGUSb( GUS_COMMAND, GUS_CMD_RESET );
                    195:     WriteGUSb( GUS_DATAHI, 1 );
                    196:     delay( 100 );
                    197: 
                    198:     // DMA Control Register reset
                    199:     WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMDMACTRL );
                    200:     WriteGUSb( GUS_DATAHI, 0 );
                    201:     delay( 10 );
                    202: 
                    203:     // Timer Control Register
                    204:     WriteGUSb( GUS_COMMAND, GUS_CMD_TIMERCTRL );
                    205:     WriteGUSb( GUS_DATAHI, 0 );
                    206:     delay( 10 );
                    207: 
                    208:     // Sampling Control Register
                    209:     WriteGUSb( GUS_COMMAND, GUS_CMD_SAMPLECTRL );
                    210:     WriteGUSb( GUS_DATAHI, 0 );
                    211:     delay( 10 );
                    212: 
                    213:     // Number of Voices
                    214:     WriteGUSb( GUS_COMMAND, GUS_CMD_ACTIVEVOICESW );
                    215:     WriteGUSb( GUS_DATAHI, 0xc0 | (14-1) );             // 14 Voices (left/right)
                    216: 
                    217:     // Evtl. anstehende DMA-IRQ's holen
                    218:     ReadGUSb( GUS_IRQSTATE );
                    219:     WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMDMACTRL );
                    220:     ReadGUSb( GUS_DATAHI );
                    221: 
                    222:     // Evtl. Sampleinterrupts lesen
                    223:     WriteGUSb( GUS_COMMAND, GUS_CMD_SAMPLECTRL );
                    224:     ReadGUSb( GUS_DATAHI );
                    225: 
                    226:     // IRQ-Status lesen
                    227:     WriteGUSb( GUS_COMMAND, GUS_CMD_IRQSOURCER );
                    228:     ReadGUSb( GUS_DATAHI );
                    229: 
                    230:     // Alle Stimmen abschalten
                    231: 
                    232:     for( i=0; i<32; i++ )
                    233:     {
                    234:          WriteGUSb( GUS_VOICE, (UBYTE)i );
                    235:          WriteGUSb( GUS_COMMAND, GUS_CMD_VOICECTRLW );
                    236:          WriteGUSb( GUS_DATAHI, 3 );                // Stimme stoppen
                    237:          WriteGUSb( GUS_COMMAND, GUS_CMD_VOLUMECTRLW );
                    238:          WriteGUSb( GUS_DATAHI, 3 );                // Lautstaerke 0
                    239:          WriteGUSb( GUS_COMMAND, GUS_CMD_RAMPRATEW );
                    240:          WriteGUSb( GUS_DATAHI, 0 );                // Ramp 0
                    241: 
                    242:     }
                    243: 
                    244:     // Evtl. anstehende DMA-IRQ's holen
                    245:     ReadGUSb( GUS_IRQSTATE );
                    246:     WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMDMACTRL );
                    247:     ReadGUSb( GUS_DATAHI );
                    248: 
                    249:     // Evtl. Sampleinterrupts lesen
                    250:     WriteGUSb( GUS_COMMAND, GUS_CMD_SAMPLECTRL );
                    251:     ReadGUSb( GUS_DATAHI );
                    252: 
                    253:     // IRQ-Status lesen
                    254:     WriteGUSb( GUS_COMMAND, GUS_CMD_IRQSOURCER );
                    255:     ReadGUSb( GUS_DATAHI );
                    256: 
                    257: 
                    258:     // Reset beenden und GF1 Master IRQ einschalten
                    259:     WriteGUSb( GUS_COMMAND, GUS_CMD_RESET );
                    260:     WriteGUSb( GUS_DATAHI, 7 );
                    261: 
                    262: 
                    263:     if( ubGUSDMA1 == 0 )     // IRQ's und DMA einstellen ?
                    264:         return;             // Nein, dann Ende
                    265: 
                    266: 
                    267:     // Digital ASIC einstellen
                    268: 
                    269:     WriteGUSb( GUS_REGISTERCTRL, 5 );   // IRQ's-Register waehlen
                    270:     WriteGUSb( GUS_MIXER, 1|2 );    // Alles Abschalten
                    271:     WriteGUSb( GUS_IRQCTRL, 0 );    // IRQ's loeschen
                    272:     WriteGUSb( GUS_REGISTERCTRL, 0 );   // Alte Registerkonfig wieder einschalten
                    273: 
                    274:     // DMA selektieren
                    275: 
                    276:     nDMA=0;
                    277:     for( j=0; j<2; j++ )
                    278:     {
                    279:         switch( ((j!=0)?(ubGUSDMA1):(ubGUSDMA2)) )
                    280:         {
                    281:             case 1:
                    282:                 nDMA |= 1;
                    283:                 break;
                    284:             case 3:
                    285:                 nDMA |= 2;
                    286:                 break;
                    287:             case 5:
                    288:                 nDMA |= 3;
                    289:                 break;
                    290:             case 6:
                    291:                 nDMA |= 4;
                    292:                 break;
                    293:             case 7:
                    294:                 nDMA |= 5;
                    295:                 break;
                    296:         }
                    297:         if( j==0 )
                    298:             nDMA=nDMA<<3;
                    299:     }
                    300: 
                    301:     if( ubGUSDMA1 == ubGUSDMA2 )    // Gleichen DMA fuer beides ?
                    302:         nDMA = (nDMA&0x3)|(1<<6);
                    303: 
                    304: 
                    305:     // Interrupt der GUS setzen
                    306: 
                    307:     nInt=0;
                    308:     for( j=0; j<2; j++ )
                    309:     {
                    310:         switch( (j!=0)?(ubGUSGF1Int):(ubGUSMIDIInt) )
                    311:         {
                    312:             case 2:
                    313:                 nInt |= 1;
                    314:                 break;
                    315:             case 5:
                    316:                 nInt |= 2;
                    317:                 break;
                    318:             case 3:
                    319:                 nInt |= 3;
                    320:                 break;
                    321:             case 7:
                    322:                 nInt |= 4;
                    323:                 break;
                    324:             case 11:
                    325:                 nInt |= 5;
                    326:                 break;
                    327:             case 12:
                    328:                 nInt |= 6;
                    329:                 break;
                    330:             case 15:
                    331:                 nInt |= 7;
                    332:                 break;
                    333:         }
                    334:         if( j==0 )
                    335:             nInt=nInt<<3;
                    336:     }
                    337: 
                    338:     if( ubGUSGF1Int == ubGUSMIDIInt )
                    339:         nInt = (nInt&0x3)|(1<<6);
                    340: 
                    341: 
                    342: 
                    343:     disable();
                    344: 
                    345:     WriteGUSb( GUS_MIXER, 1|2 );     // DMA-Einstellung aktivieren
                    346:     WriteGUSb( GUS_DMACTRL, nDMA | 0x80 );    // DMA-Kanal selektieren, welcher im SET angegebe wurde
                    347: 
                    348: 
                    349:     WriteGUSb( GUS_MIXER, 1|2|64 );  // IRQ's selektieren
                    350:     WriteGUSb( GUS_IRQCTRL, nInt );
                    351: 
                    352:     WriteGUSb( GUS_MIXER, 1|2 );     // DMA-Einstellung aktivieren
                    353:     WriteGUSb( GUS_DMACTRL, nDMA );  // DMA-Kanal selektieren, welcher im SET angegebe wurde
                    354: 
                    355:     WriteGUSb( GUS_MIXER, 1|2|64 );  // IRQ's selektieren
                    356:     WriteGUSb( GUS_IRQCTRL, nInt );
                    357: 
                    358:     enable();
                    359: 
                    360:     // IRQ/DMA locken
                    361: 
                    362:     WriteGUSb( GUS_VOICE, 0 );
                    363: 
                    364:     WriteGUSb( GUS_MIXER, 8 | ((ubGUSGF1Int==ubGUSMIDIInt)?16:0 ) );
                    365: 
                    366:     WriteGUSb( GUS_VOICE, 0 );
                    367: 
                    368: 
                    369: 
                    370: }
                    371: 
                    372: 
                    373: 
                    374: /*******************************
                    375: 
                    376:     int GUS_Init( void )
                    377: 
                    378: *******************************/
                    379: 
                    380: int GUS_Init( int *dspbits, int *rate, int *sndbufsize )
                    381: {
                    382: 
                    383:     char *szGUSENVStr, *pz;
                    384:     int i, j;
                    385:     extern void (*SND_Write)(void *buf, unsigned long size);
                    386: 
                    387: 
                    388: 
                    389:     szGUSENVStr = getenv( "ULTRASND" );
                    390:     if( szGUSENVStr == 0 )
                    391:         return 0;
                    392: 
                    393: 
                    394:     if( (*dspbits != 8 ) && (*dspbits != 16 ) )
                    395:     {
                    396:        printf( "%d bits are not supported on the GUS !\n", dspbits );
                    397:        return 0;
                    398:     }
                    399: 
                    400: 
                    401:     ubGUSUsedBits = (*dspbits==8)?0:4;
                    402: 
                    403:     if( (*rate < 1000) || (*rate > 44100 ))
                    404:     {
                    405:        fprintf( stderr, "%dHz are not supported on the GUS !\n", *rate );
                    406:        return 0;
                    407:     }
                    408: 
                    409:     uwGUSUsedFreq = *rate;
                    410: 
                    411:     // Some settings for different depths and frequencies
                    412: 
                    413: 
                    414:     if( uwGUSUsedFreq <= 12000 )
                    415:     {
                    416:        ulDMABufMaxSize = 2048;
                    417:        ulGUSSndBufSize = 32768;
                    418:     }
                    419:     else
                    420:     {
                    421:        if( uwGUSUsedFreq <= 24000 )
                    422:        {
                    423:            ulDMABufMaxSize = 4096;
                    424:            ulGUSSndBufSize = 65536;
                    425:        }
                    426:        else
                    427:        {
                    428:            ulDMABufMaxSize = 8192;
                    429:            ulGUSSndBufSize = 128*1024;
                    430:        }
                    431:     }
                    432: 
                    433:     if( ubGUSUsedBits == 0 )
                    434:     {
                    435:        *sndbufsize = 256;      // 256 bytes, wenn 8 Bit
                    436:     }
                    437:     else
                    438:     {
                    439:        *sndbufsize = 512;
                    440:        ulDMABufMaxSize *= 2;   // Double it, if 16 bit
                    441:        ulGUSSndBufSize *= 2;
                    442:     }
                    443: 
                    444:     fprintf( stderr, "GUS configured for %d bits, %d Hz\n", *dspbits, *rate );
                    445:     fprintf( stderr, "Soundbuffersize: %d bytes\n", ulGUSSndBufSize );
                    446:     fprintf( stderr, "DMA-buffersize: %d bytes\n", ulDMABufMaxSize );
                    447:     fprintf( stderr, "Fragmentsize: %d bytes\n", *sndbufsize );
                    448: 
                    449: 
                    450:     uwGUSPort = (UWORD)strtol( szGUSENVStr, (char **)NULL, 16 );
                    451:     pz = strchr( szGUSENVStr, ',' );
                    452:     if( (pz == 0) || (uwGUSPort ==0)  )
                    453:         return 0;
                    454: 
                    455:     ubGUSDMA1 = (UBYTE)atol( pz+1 );
                    456:     pz = strchr( pz+1, ',' );
                    457:     if( pz == 0 )
                    458:         return 0;
                    459: 
                    460:     ubGUSDMA2 = (UBYTE)atol( pz+1 );
                    461: 
                    462:     pz = strchr( pz+1, ',' );
                    463:     if( pz == 0 )
                    464:         return 0;
                    465: 
                    466:     ubGUSGF1Int = (UBYTE)atol( pz+1 );
                    467:     if( ubGUSGF1Int == 0 )
                    468:         return 0;
                    469: 
                    470:     pz = strchr( pz+1, ',' );
                    471:     if( pz == 0 )
                    472:         return 0;
                    473: 
                    474:     ubGUSMIDIInt = (UBYTE)atol( pz+1 );
                    475:     if( ubGUSMIDIInt == 0 )
                    476:         return 0;
                    477: 
                    478:     // Speicher fuer DMA holen
                    479: 
                    480: 
                    481:     memset( &dma_mem, 0, sizeof( _go32_dpmi_seginfo ) );
                    482:     dma_mem.size = NUMPARAS( ulDMABufMaxSize+1000 );
                    483:     dmabufadr = DMA_AllocDMABuf( &dma_mem );
                    484: 
                    485: 
                    486:     _go32_dpmi_lock_code( GUS_PlayBuffer, (ULONG)GUS_DummyFunc - (ULONG)GUS_PlayBuffer);
                    487:     _go32_dpmi_lock_data( &uwGUSPort, (ULONG)&ubDummy - (ULONG)&uwGUSPort);
                    488: 
                    489: 
                    490:     if( dmabufadr == NULL)
                    491:     {
                    492:       fprintf( stderr, "Cannot allocate DOS memory for DMA buffers!\n" );
                    493:       return 0;
                    494:     }
                    495: 
                    496: 
                    497:     // Zwischenpuffer allokieren
                    498: 
                    499:     pGUSBuffer = (UBYTE *)malloc( ulGUSSndBufSize+1000 );
                    500:     if( pGUSBuffer == 0 )
                    501:     {
                    502:         fprintf( stderr, "Cannot allocate soundbuffer !\n" );
                    503:         return 0;
                    504:     }
                    505: 
                    506:     nGUSBufferWriteIndex = nGUSBufferReadIndex = ulBytesInBuffer = 0;
                    507: 
                    508:     // GUS-Reset
                    509: 
                    510:     GUS_Reset( ubGUSDMA1, ubGUSDMA2, ubGUSGF1Int );
                    511: 
                    512: 
                    513:     // Test, ob wir in das GUS-RAM etwas schreiben koennen
                    514: 
                    515:     WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMIOADRLO );
                    516:     WriteGUSw( GUS_DATALO, 0 );
                    517:     WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMIOADRHI );
                    518:     WriteGUSw( GUS_DATAHI, 0 );
                    519: 
                    520:     WriteGUSb( GUS_DRAM, 0x15 );
                    521:     delay( 100 );
                    522:     if( ReadGUSb( GUS_DRAM ) != 0x15 )      // Bytes unterschiedlich ?
                    523:         return 0;
                    524: 
                    525:     // GUS-RAM loeschen
                    526: 
                    527:     j=-1;
                    528:     for( i=0; i<(int)(ulDMABufMaxSize*2+1000); i++ )
                    529:     {
                    530:         if( j != MSW(i) )       // Muss das Highword veraendert werden `?
                    531:         {
                    532:             j = MSW(i);
                    533: 
                    534:             WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMIOADRHI );
                    535:             WriteGUSw( GUS_DATALO, MSW( i ) );
                    536:         }
                    537: 
                    538:         WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMIOADRLO );
                    539:         WriteGUSw( GUS_DATALO,  LSW( i ) );
                    540: 
                    541:         WriteGUSb( GUS_DRAM, 0 );
                    542: 
                    543:     }
                    544: 
                    545: 
                    546:     // Interrupthandler installieren
                    547: 
                    548:     memset( &pm_wrapperGF1, 0, sizeof( _go32_dpmi_seginfo ) );
                    549:     pm_wrapperGF1.pm_offset = (int) GUS_GF1InterruptHandler;
                    550:     if(_go32_dpmi_allocate_iret_wrapper( &pm_wrapperGF1 ) )
                    551:     {
                    552:         fprintf( stderr, "Cannot allocate protected mode wrapper for GUS interrupt!\n");
                    553:         if( dmabufadr != 0 )
                    554:             _go32_dpmi_free_dos_memory( &dma_mem );
                    555: 
                    556:         return 0;
                    557:     }
                    558: 
                    559: 
                    560:     ubGUSGF1IRQVector = (ubGUSGF1Int>7)?(ubGUSGF1Int+0x68):(ubGUSGF1Int+0x08);   // Physik. Vektor berechnen
                    561: 
                    562:     _go32_dpmi_get_protected_mode_interrupt_vector( ubGUSGF1IRQVector, &old_pmintGF1 );   // Alten Interrupt merken
                    563:     _go32_dpmi_set_protected_mode_interrupt_vector( ubGUSGF1IRQVector, &pm_wrapperGF1 );  // Neuen Interrupt merken
                    564: 
                    565: 
                    566:     // Interrupt erlauben
                    567: 
                    568:     if( ubGUSGF1Int > 7 )
                    569:     {
                    570:         outportb( 0xA1, inportb( 0xA1 ) & ~(1 << ( ubGUSGF1Int-8 ) ) );
                    571:         outportb( 0xA0, 0x20 );
                    572:     }
                    573:     else
                    574:     {
                    575:         outportb( 0x21, inportb( 0x21 ) & ~(1 << ubGUSGF1Int));
                    576:         outportb( 0x20, 0x20 );
                    577:     }
                    578: 
                    579: 
                    580:     // Hier wird die Stimme zum erstenmal gestertet
                    581: 
                    582: 
                    583:     WriteGUSb( GUS_VOICE, 0 );                      // Stimme0
                    584: 
                    585:     WriteGUSb( GUS_COMMAND, GUS_CMD_VOLUMEW );      // Lautstaerke auf Maximum
                    586:     WriteGUSw( GUS_DATALO, 61247 );
                    587: 
                    588:     WriteGUSb( GUS_COMMAND, GUS_CMD_FREQUCTRLW );   // 14 Stimmen = x / 43!
                    589:     WriteGUSw( GUS_DATALO, uwGUSUsedFreq/43 );
                    590: 
                    591: 
                    592:     WriteGUSb( GUS_COMMAND, GUS_CMD_CURRENTLOW );   // Current
                    593:     WriteGUSw( GUS_DATALO, 32 );
                    594:     WriteGUSb( GUS_COMMAND, GUS_CMD_CURRENTHIW );
                    595:     WriteGUSw( GUS_DATALO, 0 );
                    596: 
                    597:     WriteGUSb( GUS_COMMAND, GUS_CMD_STARTHIW );     // Start
                    598:     WriteGUSw( GUS_DATALO, 0 );
                    599:     WriteGUSb( GUS_COMMAND, GUS_CMD_STARTLOW );
                    600:     WriteGUSw( GUS_DATALO, 32 );
                    601: 
                    602:     if( ubGUSUsedBits == 0 )        // 8 oder 16 Bit ?
                    603:     {
                    604:         WriteGUSb( GUS_COMMAND, GUS_CMD_ENDHIW );       // Ende setzen
                    605:         WriteGUSw( GUS_DATALO, ADDR_HI( ulDMABufMaxSize+32 ) );
                    606:         WriteGUSb( GUS_COMMAND, GUS_CMD_ENDLOW );
                    607:         WriteGUSw( GUS_DATALO, ADDR_LO( ulDMABufMaxSize+32 ) );
                    608:     }
                    609:     else
                    610:     {
                    611:         WriteGUSb( GUS_COMMAND, GUS_CMD_ENDHIW );       // Ende
                    612:         WriteGUSw( GUS_DATALO, ADDR_HI( CONVTO16B( ulDMABufMaxSize+32 ) ) );
                    613:         WriteGUSb( GUS_COMMAND, GUS_CMD_ENDLOW );
                    614:         WriteGUSw( GUS_DATALO, ADDR_LO( CONVTO16B( ulDMABufMaxSize+32 ) ) );
                    615:     }
                    616: 
                    617:     WriteGUSb( GUS_COMMAND, GUS_CMD_VOLUMECTRLW );
                    618:     WriteGUSb( GUS_DATAHI, 3|4 );
                    619:     GUS_GF1Delay();
                    620:     WriteGUSb( GUS_DATAHI, 3|4 );         // Rollover an
                    621: 
                    622: 
                    623:     WriteGUSb( GUS_COMMAND, GUS_CMD_VOICECTRLW );
                    624:     WriteGUSb( GUS_DATAHI, 32|ubGUSUsedBits );
                    625:     GUS_GF1Delay();
                    626:     WriteGUSb( GUS_DATAHI, 32|ubGUSUsedBits );  // Stimme starten, Loop aus
                    627: 
                    628: 
                    629:     bIgnoreGF1IRQ = FALSE;
                    630: 
                    631: 
                    632:     // GUS-Initialisierung beendet, puhhh
                    633: 
                    634:     fprintf( stderr, "GUS found at port: %Xh, dma1: %d, dma2: %d, GF1-int: %d, MIDI-int: %d\n", uwGUSPort, ubGUSDMA1, ubGUSDMA2, ubGUSGF1Int, ubGUSMIDIInt );
                    635: 
                    636: 
                    637:     atexit( GUS_Cleanup );
                    638: 
                    639: 
                    640:     SND_Write = GUS_PlayBuffer;
                    641: 
                    642: 
                    643:     return 1;
                    644: 
                    645: }
                    646: 
                    647: 
                    648: /*******************************
                    649: 
                    650:     int GUS_Cleanup( void )
                    651: 
                    652: *******************************/
                    653: 
                    654: 
                    655: void GUS_Cleanup( void )
                    656: {
                    657: 
                    658: 
                    659:     fprintf( stderr, "Freeing up all GUS-stuff\n" );
                    660: 
                    661:     // Warten, bis DMA beendet ist
                    662: 
                    663:     if( bDMAInProgress == TRUE )
                    664:     {
                    665:         do
                    666:         {
                    667:             delay( 10 );
                    668:         }
                    669:         while( bDMAInProgress == TRUE );
                    670:     }
                    671: 
                    672: 
                    673:     // Stimmen anhalten
                    674: 
                    675:     WriteGUSb( GUS_VOICE, 0 );
                    676: 
                    677:     WriteGUSb( GUS_COMMAND, GUS_CMD_VOLUMECTRLW );
                    678:     WriteGUSb( GUS_DATAHI, 3 );
                    679:     GUS_GF1Delay();
                    680:     WriteGUSb( GUS_DATAHI, 3 );
                    681: 
                    682: 
                    683:     WriteGUSb( GUS_COMMAND, GUS_CMD_VOICECTRLW );
                    684:     WriteGUSb( GUS_DATAHI, 3 );
                    685:     GUS_GF1Delay();
                    686:     WriteGUSb( GUS_DATAHI, 3 );
                    687: 
                    688:     // GUS resetten
                    689: 
                    690:     GUS_Reset( 0, 0, 0 );
                    691: 
                    692:     // Interrupts wieder sperren
                    693: 
                    694:     if( ubGUSGF1Int > 7 )
                    695:         outportb (0xA1, inportb(0xA1) | (1 << (ubGUSGF1Int-8)));
                    696:     else
                    697:         outportb (0x21, inportb(0x21) | (1 << ubGUSGF1Int));
                    698: 
                    699:     _go32_dpmi_set_protected_mode_interrupt_vector( ubGUSGF1IRQVector, &old_pmintGF1 );
                    700:     _go32_dpmi_free_iret_wrapper( &pm_wrapperGF1 );
                    701: 
                    702: 
                    703:     // Speicher freigeben
                    704: 
                    705:     if( pGUSBuffer != 0 )
                    706:         free( pGUSBuffer );
                    707: 
                    708:     if( dmabufadr != 0 )
                    709:         _go32_dpmi_free_dos_memory( &dma_mem );  // Speicher fuer DMA freigeben
                    710: 
                    711:     GUS_Reset( 0, 0, 0 );
                    712: 
                    713: }
                    714: 
                    715: /*******************************
                    716: 
                    717:     void GUS_PlayBuffer( void *buf, unsigned long size )
                    718: 
                    719: *******************************/
                    720: 
                    721: 
                    722: // Diese Routine wird vom UAE aufgerufen, wenn der Soundbuffer
                    723: // zu leeren ist
                    724: 
                    725: 
                    726: void GUS_PlayBuffer( void *buf, unsigned long size )
                    727: {
                    728:     ULONG            i;
                    729: 
                    730: 
                    731: 
                    732:     disable();
                    733: 
                    734:     // Daten in den GUS-Buffer kopieren
                    735: 
                    736:     if( size+ulBytesInBuffer>ulGUSSndBufSize )
                    737:     {
                    738:         fprintf( stderr, "Error: GUS-soundbuffer overflow !\n" );
                    739:     }
                    740:     else
                    741:     {
                    742:         // Better playing the voice faster than getting an overflow !
                    743: 
                    744:         if( (ulBytesInBuffer> (ulGUSSndBufSize/2+ulGUSSndBufSize/4) )
                    745:             && (bVoicesFast == TRUE ) )
                    746:                                                     // Is the Buffer going
                    747:         {                                           // to overflow ?
                    748: 
                    749: //            fprintf( stderr, "Warping voice up ... (scotty, I need more power)\n" );
                    750: 
                    751: 
                    752:             WriteGUSb( GUS_VOICE, 0 );
                    753: 
                    754:             WriteGUSb( GUS_COMMAND, GUS_CMD_FREQUCTRLW );
                    755:             WriteGUSw( GUS_DATALO, (uwGUSUsedFreq+(uwGUSUsedFreq>>2))/43 ); // 25% faster
                    756:         }
                    757: 
                    758:         if( (ulBytesInBuffer> ulGUSSndBufSize/2 )
                    759:             && (bVoicesFast == FALSE ) )
                    760:                                                     // Is the Buffer going
                    761:         {                                           // to overflow ?
                    762: 
                    763: //            fprintf( stderr, "Speeding voice up ...\n" );
                    764: 
                    765: 
                    766:             WriteGUSb( GUS_VOICE, 0 );
                    767: 
                    768:             WriteGUSb( GUS_COMMAND, GUS_CMD_FREQUCTRLW );
                    769:             WriteGUSw( GUS_DATALO, (uwGUSUsedFreq+uwGUSUsedFreq/10)/43 ); // 10% faster
                    770: 
                    771: 
                    772:             bVoicesFast = TRUE;
                    773: 
                    774:         }
                    775: 
                    776:         if( (bVoicesFast == TRUE) && (ulBytesInBuffer < ulGUSSndBufSize/4 ) )
                    777:         {
                    778: //            fprintf( stderr, "Slowing voice down to normal speed\n" );
                    779: 
                    780:             WriteGUSb( GUS_VOICE, 0 );
                    781: 
                    782:             WriteGUSb( GUS_COMMAND, GUS_CMD_FREQUCTRLW );
                    783:             WriteGUSw( GUS_DATALO, uwGUSUsedFreq/43 ); // Normal speed
                    784: 
                    785:             bVoicesFast = FALSE;
                    786: 
                    787: 
                    788:         }
                    789: 
                    790: 
                    791:         // GUS-Buffer fuellen
                    792: 
                    793:         // Koennen wir auf einmal kopieren ?
                    794: 
                    795:         i = ulGUSSndBufSize-nGUSBufferWriteIndex;
                    796:         if( i < size )
                    797:         {
                    798:             memcpy( pGUSBuffer+nGUSBufferWriteIndex, buf, i );
                    799: 
                    800:             memcpy( pGUSBuffer, ((UBYTE*)buf)+i, size-i );
                    801: 
                    802:         }
                    803:         else
                    804:         {
                    805:             memcpy( pGUSBuffer+nGUSBufferWriteIndex, buf, size );
                    806:         }
                    807: 
                    808:         nGUSBufferWriteIndex = (nGUSBufferWriteIndex+size)&(ulGUSSndBufSize-1);
                    809: 
                    810:         ulBytesInBuffer += size;
                    811: 
                    812:     }
                    813: 
                    814:     enable();
                    815: 
                    816: }
                    817: 
                    818: 
                    819: /*******************************
                    820: 
                    821: void GUS_StartDMA( ULONG ulPosInGUSRAM )
                    822: 
                    823: *******************************/
                    824: 
                    825: 
                    826: 
                    827: void GUS_StartDMA( ULONG ulPosInGUSRAM, int bLoop )
                    828: {
                    829: 
                    830:     ULONG   i, pDMABuf, j;
                    831:     ULONG   ulTemp;
                    832: 
                    833:     // I hope, everything is aligned to 4 byte (32bit), otherwise
                    834:     // the machine my crash :(
                    835: 
                    836: 
                    837:     if( bDMAInProgress == TRUE )
                    838:     {
                    839:         fprintf( stderr, "Error in StartDMA, DMA already im progress !\n" );
                    840:         return;
                    841:     }
                    842: 
                    843:     bDMAInProgress=TRUE;
                    844: 
                    845:     // Kopiert die Daten aus dem Soundbuffer in den DMA-Puffer
                    846: 
                    847: 
                    848:     _farsetsel( _dos_ds );
                    849: 
                    850:     if( ulBytesInBuffer == 0 )      // Sind ueberhaupt Daten im Puffer ?
                    851:     {                               // Nein, dann DMA-Buffer loeschen
                    852:         pDMABuf = dmabufadr;
                    853: 
                    854:         if( ubGUSUsedBits == 0 )    // 8 Bit ?
                    855:             ulTemp = 0x80808080;
                    856:         else
                    857:             ulTemp = 0;
                    858: 
                    859:         for( i=ulDMABufMaxSize/4; i>0; i-- )
                    860:         {
                    861:             _farnspokel( pDMABuf, ulTemp );
                    862:             pDMABuf+=4;
                    863:         }
                    864: 
                    865:     }
                    866:     else
                    867:     {
                    868:         if( ulBytesInBuffer >= ulDMABufMaxSize )    // Sind mehr Daten da, als
                    869:         {                                           // der Puffer gross ist ?
                    870: 
                    871:             pDMABuf = dmabufadr;                    // Ja, DMA-Puffer vollmachen
                    872: 
                    873:             j = nGUSBufferReadIndex;
                    874:             for( i=ulDMABufMaxSize/4; i>0; i-- )
                    875:             {
                    876:                 _farnspokel( pDMABuf, *((ULONG*)(pGUSBuffer+j)) );  // 32 bit-copy
                    877:                 pDMABuf+=4;
                    878:                 j = (j+4)&(ulGUSSndBufSize-1);
                    879:             }
                    880: 
                    881:             nGUSBufferReadIndex = (nGUSBufferReadIndex+ulDMABufMaxSize)&(ulGUSSndBufSize-1);
                    882: 
                    883:             ulBytesInBuffer -= ulDMABufMaxSize;
                    884:         }
                    885:         else
                    886:         {
                    887:             pDMABuf = dmabufadr;          // Nein, nur den vorhanden Teil
                    888:                                           // kopieren
                    889: 
                    890:             j = nGUSBufferReadIndex;
                    891:             for( i=ulBytesInBuffer/4; i>0; i-- )
                    892:             {
                    893:                 _farnspokel( pDMABuf, *((ULONG*)(pGUSBuffer+j)) );
                    894:                 pDMABuf+=4;
                    895:                 j = (j+4)&(ulGUSSndBufSize-1);
                    896:             }
                    897:             nGUSBufferReadIndex = (nGUSBufferReadIndex+ulBytesInBuffer)&(ulGUSSndBufSize-1);
                    898: 
                    899: 
                    900:             if( ubGUSUsedBits == 0 )     // 8 Bit ?
                    901:                 ulTemp = 0x80808080;
                    902:             else
                    903:                 ulTemp = 0;
                    904: 
                    905: 
                    906:             for( i=(ulDMABufMaxSize-ulBytesInBuffer)/4; i>0; i-- )
                    907:             {
                    908:                 _farnspokel( pDMABuf, ulTemp );
                    909:                 pDMABuf+=4;
                    910:             }
                    911: 
                    912: 
                    913:             ulBytesInBuffer = 0;
                    914:         }
                    915: 
                    916:     }
                    917: 
                    918: 
                    919:     if( bLoop == TRUE ) // Byte/Word kopieren, um das Geklicke zu verhindern ?
                    920:     {
                    921: 
                    922:         if( ubGUSUsedBits == 0 )    // 8 Bit ?
                    923:         {
                    924: 
                    925:             WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMIOADRHI );
                    926:             WriteGUSw( GUS_DATALO, MSW( ulPosInGUSRAM-ulDMABufMaxSize-1 ) );
                    927: 
                    928:             WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMIOADRLO );
                    929:             WriteGUSw( GUS_DATALO, LSW( ulPosInGUSRAM-ulDMABufMaxSize-1 ) );
                    930: 
                    931:             WriteGUSb( GUS_DRAM, _farnspeekb( dmabufadr+ulDMABufMaxSize-1 )+0x80 );
                    932: 
                    933:         }
                    934:         else
                    935:         {
                    936:             WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMIOADRHI );
                    937:             WriteGUSw( GUS_DATALO, MSW( ulPosInGUSRAM-ulDMABufMaxSize-2 ) );
                    938: 
                    939:             WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMIOADRLO );
                    940:             WriteGUSw( GUS_DATALO, LSW( ulPosInGUSRAM-ulDMABufMaxSize-2 ) );
                    941: 
                    942:             WriteGUSb( GUS_DRAM, _farnspeekb( dmabufadr+ulDMABufMaxSize-2 ) );
                    943: 
                    944:             WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMIOADRHI );
                    945:             WriteGUSw( GUS_DATALO, MSW( ulPosInGUSRAM-ulDMABufMaxSize-1 ) );
                    946: 
                    947:             WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMIOADRLO );
                    948:             WriteGUSw( GUS_DATALO, LSW( ulPosInGUSRAM-ulDMABufMaxSize-1 ) );
                    949: 
                    950:             WriteGUSb( GUS_DRAM, _farnspeekb( dmabufadr+ulDMABufMaxSize-1 ) );
                    951: 
                    952:         }
                    953: 
                    954:     }
                    955: 
                    956: 
                    957:     // DMA-Controller initialisieren
                    958:     DMA_InitTransfer( ubGUSDMA1, DMA_READ, dmabufadr, ulDMABufMaxSize );
                    959: 
                    960:     // GUS-Register initialisieren
                    961:     WriteGUSb( GUS_COMMAND, GUS_CMD_DMASTARTADR );
                    962:     if( ubGUSDMA1>3 )
                    963:         WriteGUSw( GUS_DATALO, CONVTO16B(ulPosInGUSRAM>>4) ); // Adresse>>4 !!!!
                    964:     else
                    965:         WriteGUSw( GUS_DATALO, (UWORD)(ulPosInGUSRAM>>4) ); // Adresse>>4 !!!!
                    966: 
                    967:     if( ubGUSUsedBits == 0 )
                    968:     {                               // 8 Bit
                    969:         if( ubGUSDMA1>3 )
                    970:         {
                    971:             WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMDMACTRL );
                    972:             WriteGUSb( GUS_DATAHI, 0x85 | 0x20 );   // Mit signed->unsigned kopieren
                    973: 
                    974:         }
                    975:         else
                    976:         {
                    977:             WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMDMACTRL );
                    978:             WriteGUSb( GUS_DATAHI, 0x81 | 0x20 );
                    979:         }
                    980:     }
                    981:     else
                    982:     {                       // 16 Bit
                    983:         if( ubGUSDMA1>3 )
                    984:         {
                    985:             WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMDMACTRL );
                    986:             WriteGUSb( GUS_DATAHI, 0x05 | 0x20 );   // Ohne signed->unsigned kopieren
                    987: 
                    988:         }
                    989:         else
                    990:         {
                    991:             WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMDMACTRL );
                    992:             WriteGUSb( GUS_DATAHI, 0x01 | 0x20 );
                    993:         }
                    994: 
                    995: 
                    996:     }
                    997: 
                    998: }
                    999: 
                   1000: 
                   1001: 
                   1002: /*******************************
                   1003: 
                   1004:     void GUS_WorkOnVoices( void )
                   1005: 
                   1006: *******************************/
                   1007: 
                   1008: 
                   1009: // Hier werden die Interrupts der einzelnen Stimmen bearbeitet
                   1010: 
                   1011: void GUS_WorkOnVoices( void )
                   1012: {
                   1013: 
                   1014:     UBYTE ubIntArt, ubTemp1, ubTemp2;
                   1015:     int i, nVoice, nVoiceBit, nWaveIgnore=0, nVolumeIgnore=0;
                   1016:     int nIntCounts=0;
                   1017: 
                   1018:     // Alle anstehenden Interrupts bearbeiten
                   1019: 
                   1020:     for(;;)
                   1021:     {
                   1022: 
                   1023: 
                   1024:         WriteGUSb( GUS_COMMAND, GUS_CMD_IRQSOURCER );   // IRQ-Art holen
                   1025:         ubIntArt = ReadGUSb( GUS_DATAHI );
                   1026: 
                   1027:         nVoice = ubIntArt & 0x1f;
                   1028:         nVoiceBit = ((ULONG)1)<<((ULONG)nVoice);
                   1029: 
                   1030:         // Alle Interrupts abgearbeitet ?
                   1031:         if( ( ubIntArt & 192) == 192 )      // Negative Logik !!!!
                   1032:         {
                   1033:             break;
                   1034:         }
                   1035: 
                   1036:         nIntCounts++;
                   1037: 
                   1038:         if( nIntCounts>3 )
                   1039:         {
                   1040:             #ifdef DEBUG
                   1041:             fprintf( stderr, "!!!! Breche Int. ab, da mehr als 3 Anfragen !!!\n" );
                   1042:             #endif
                   1043: 
                   1044:             WriteGUSb( GUS_COMMAND, GUS_CMD_VOLUMECTRLW );
                   1045:             WriteGUSb( GUS_DATAHI, 3 );
                   1046:             GUS_GF1Delay();
                   1047:             WriteGUSb( GUS_DATAHI, 3 );
                   1048: 
                   1049:             WriteGUSb( GUS_COMMAND, GUS_CMD_VOICECTRLW );
                   1050:             WriteGUSb( GUS_DATAHI, 3 );
                   1051:             GUS_GF1Delay();
                   1052:             WriteGUSb( GUS_DATAHI, 3 );
                   1053: 
                   1054:             return;
                   1055:         }
                   1056: 
                   1057:         if( bIgnoreGF1IRQ == TRUE )
                   1058:         {
                   1059:             #ifdef DEBUG
                   1060:             fprintf( stderr, "\t\tIgnoriere IRQ !\n" );
                   1061:             #endif
                   1062: 
                   1063:             WriteGUSb( GUS_COMMAND, GUS_CMD_VOICECTRLW );
                   1064:             WriteGUSb( GUS_DATAHI, 3 );      // Loop aus, IRQ aus
                   1065: 
                   1066:             WriteGUSb( GUS_COMMAND, GUS_CMD_VOLUMECTRLW );
                   1067:             WriteGUSb( GUS_DATAHI, 3 );   // Rollover an, IRQ an
                   1068:         }
                   1069: 
                   1070:         #ifdef DEBUG
                   1071:         fprintf( stderr, "\tBearbeite Stimme %d, IntArt: $%X\n", nVoice, ubIntArt );
                   1072:         #endif
                   1073: 
                   1074:         if( ! (ubIntArt & 128 ) )           // WAVE-Table-IRQ ?
                   1075:         {
                   1076:             if( !(nWaveIgnore & nVoiceBit ))
                   1077:             {
                   1078:                 nWaveIgnore |= nVoiceBit;
                   1079: 
                   1080:                 #ifdef DEBUG
                   1081:                 fprintf( stderr,"\t\tBearbeite WAVE-IRQ\n" );
                   1082:                 #endif
                   1083: 
                   1084:                 WriteGUSb( GUS_VOICE, nVoice );
                   1085:                 WriteGUSb( GUS_COMMAND, GUS_CMD_VOICECTRLR );
                   1086:                 ubTemp1 = ReadGUSb( GUS_DATAHI );
                   1087: 
                   1088:                 WriteGUSb( GUS_COMMAND, GUS_CMD_VOLUMECTRLR );
                   1089:                 ubTemp2 = ReadGUSb( GUS_DATAHI );
                   1090: 
                   1091: 
                   1092:                 if( ubTemp2&4 )     // Ist das Rollover an ?
                   1093:                 {                   // Ja
                   1094: 
                   1095:                     // Das Ende neu setzen
                   1096: 
                   1097:                     if( ubGUSUsedBits == 0 )    // 8 Bit ?
                   1098:                     {
                   1099:                         WriteGUSb( GUS_COMMAND, GUS_CMD_ENDHIW );       // Ende setzen
                   1100:                         WriteGUSw( GUS_DATALO, ADDR_HI( ulDMABufMaxSize*2+32 ) );
                   1101:                         WriteGUSb( GUS_COMMAND, GUS_CMD_ENDLOW );
                   1102:                         WriteGUSw( GUS_DATALO, ADDR_LO( ulDMABufMaxSize*2+32 ) );
                   1103:                     }
                   1104:                     else
                   1105:                     {
                   1106:                         WriteGUSb( GUS_COMMAND, GUS_CMD_ENDHIW );       // Ende setzen
                   1107:                         WriteGUSw( GUS_DATALO, ADDR_HI( CONVTO16B( ulDMABufMaxSize*2+32 ) ) );
                   1108:                         WriteGUSb( GUS_COMMAND, GUS_CMD_ENDLOW );
                   1109:                         WriteGUSw( GUS_DATALO, ADDR_LO( CONVTO16B( ulDMABufMaxSize*2+32 ) ) );
                   1110:                     }
                   1111: 
                   1112:                     WriteGUSb( GUS_COMMAND, GUS_CMD_VOLUMECTRLW );
                   1113:                     WriteGUSb( GUS_DATAHI, 3 );
                   1114:                     GUS_GF1Delay();
                   1115:                     WriteGUSb( GUS_DATAHI, 3 );         // Rollover aus
                   1116: 
                   1117:                     WriteGUSb( GUS_COMMAND, GUS_CMD_VOICECTRLW );
                   1118:                     WriteGUSb( GUS_DATAHI, 32|8|ubGUSUsedBits );
                   1119:                     GUS_GF1Delay();
                   1120:                     WriteGUSb( GUS_DATAHI, 32|8|ubGUSUsedBits ); // Loop an
                   1121: 
                   1122:                     GUS_StartDMA( 32, FALSE );
                   1123: 
                   1124:                 }
                   1125:                 else
                   1126:                 {
                   1127: 
                   1128:                     // Das Ende neu setzen
                   1129: 
                   1130:                     if( ubGUSUsedBits == 0 )
                   1131:                     {
                   1132:                         WriteGUSb( GUS_COMMAND, GUS_CMD_ENDHIW );       // Ende setzen
                   1133:                         WriteGUSw( GUS_DATALO, ADDR_HI( ulDMABufMaxSize+32 ) );
                   1134:                         WriteGUSb( GUS_COMMAND, GUS_CMD_ENDLOW );
                   1135:                         WriteGUSw( GUS_DATALO, ADDR_LO( ulDMABufMaxSize+32 ) );
                   1136:                     }
                   1137:                     else
                   1138:                     {
                   1139:                         WriteGUSb( GUS_COMMAND, GUS_CMD_ENDHIW );       // Ende setzen
                   1140:                         WriteGUSw( GUS_DATALO, ADDR_HI( CONVTO16B( ulDMABufMaxSize+32 ) ) );
                   1141:                         WriteGUSb( GUS_COMMAND, GUS_CMD_ENDLOW );
                   1142:                         WriteGUSw( GUS_DATALO, ADDR_LO( CONVTO16B( ulDMABufMaxSize+32 ) ) );
                   1143:                     }
                   1144: 
                   1145:                     WriteGUSb( GUS_COMMAND, GUS_CMD_VOLUMECTRLW );
                   1146:                     WriteGUSb( GUS_DATAHI, 3|4 );
                   1147:                     GUS_GF1Delay();
                   1148:                     WriteGUSb( GUS_DATAHI, 3|4 );         // Rollover an
                   1149: 
                   1150:                     WriteGUSb( GUS_COMMAND, GUS_CMD_VOICECTRLW );
                   1151:                     WriteGUSb( GUS_DATAHI, 32|ubGUSUsedBits );
                   1152:                     GUS_GF1Delay();
                   1153:                     WriteGUSb( GUS_DATAHI, 32|ubGUSUsedBits ); // Loop aus
                   1154: 
                   1155:                     GUS_StartDMA( ulDMABufMaxSize+32, TRUE );
                   1156: 
                   1157:                 }
                   1158: 
                   1159:             }
                   1160:         }
                   1161: 
                   1162:         if( ! (ubIntArt & 64 ) )        // Volume-IRQ
                   1163:         {
                   1164: 
                   1165:             if( !(nVolumeIgnore & nVoiceBit ))
                   1166:             {
                   1167:                 nVolumeIgnore |= nVoiceBit;
                   1168:                 #ifdef DEBUG
                   1169:                 fprintf( stderr, "\t\tBearbeite Volume-IRQ\n" );
                   1170:                 #endif
                   1171: 
                   1172:                 WriteGUSb( GUS_VOICE, nVoice );
                   1173:                 WriteGUSb( GUS_COMMAND, GUS_CMD_VOLUMECTRLR );
                   1174:                 ubTemp2 = ReadGUSb( GUS_DATAHI );
                   1175: 
                   1176:                 WriteGUSb(GUS_COMMAND, GUS_CMD_VOICECTRLR );
                   1177:                 ubTemp1 = ReadGUSb( GUS_DATAHI );
                   1178: 
                   1179: 
                   1180:                 WriteGUSb( GUS_COMMAND, GUS_CMD_VOLUMECTRLW );
                   1181:                 WriteGUSb( GUS_DATAHI, (ubTemp2 & (~32)) | 3 );
                   1182: 
                   1183:             }
                   1184: 
                   1185:         }
                   1186: 
                   1187:     }
                   1188: }
                   1189: 
                   1190: 
                   1191: 
                   1192: /*******************************
                   1193: 
                   1194:     void GUS_GF1InterruptHandler( void )
                   1195: 
                   1196: *******************************/
                   1197: 
                   1198: 
                   1199: // Hier werden alle Interrupts verarbeitet
                   1200: 
                   1201: void GUS_GF1InterruptHandler( void )
                   1202: {
                   1203: 
                   1204:     UBYTE ubIntArt, ubTemp;
                   1205: 
                   1206: 
                   1207: 
                   1208: 
                   1209:     if( uwGUSPort == 0 )
                   1210:         return;
                   1211: 
                   1212:     #ifdef DEBUG
                   1213:     fprintf( stderr, "- Interrupt aufgetreten. Zeit: %lf\n", ((double)clock())/((double)CLOCKS_PER_SEC) );
                   1214:     #endif
                   1215: 
                   1216:     for(;;)
                   1217:     {
                   1218: 
                   1219:         ubIntArt = ReadGUSb( GUS_IRQSTATE );
                   1220: 
                   1221:         #ifdef DEBUG
                   1222:         fprintf( stderr, "  IRQ-Status (2x6): $%X\n", ubIntArt );
                   1223:         #endif
                   1224: 
                   1225: 
                   1226:         if( ubIntArt == 0 )         // Fertig ?
                   1227:             break;
                   1228: 
                   1229:         if( ubIntArt & 128 )        // TC-IRQ ?
                   1230:         {
                   1231: 
                   1232:             WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMDMACTRL );
                   1233:             if( ReadGUSb( GUS_DATAHI ) & 0x40 )
                   1234:             {
                   1235:                 #ifdef DEBUG
                   1236:                 fprintf( stderr, "  - Bearbeite DMA-Interrupt\n" );
                   1237:                 #endif
                   1238: 
                   1239:                 bDMAInProgress = FALSE;
                   1240: 
                   1241:             }
                   1242: 
                   1243:             WriteGUSb( GUS_COMMAND, GUS_CMD_SAMPLECTRL );
                   1244:             if( ReadGUSb( GUS_DATAHI ) & 0x40 )
                   1245:             {
                   1246:                 #ifdef DEBUG
                   1247:                 fprintf( stderr, "  - Bearbeite Sample-Interrupt\n" );
                   1248:                 #endif
                   1249: 
                   1250:             }
                   1251: 
                   1252:         }
                   1253: 
                   1254:         if( ubIntArt & 3 )
                   1255:         {
                   1256:             #ifdef DEBUG
                   1257:             fprintf( stderr, "  - Bearbeite MIDI-IRQ\n" );
                   1258:             #endif
                   1259: 
                   1260:         }
                   1261: 
                   1262:         if( ubIntArt & 64 )
                   1263:         {
                   1264:             #ifdef DEBUG
                   1265:             fprintf( stderr, "  - Bearbeite VOLUME-IRQ\n" );
                   1266:             #endif
                   1267:             GUS_WorkOnVoices();
                   1268: 
                   1269: 
                   1270:         }
                   1271: 
                   1272:         if( ubIntArt & 32 )
                   1273:         {
                   1274:             #ifdef DEBUG
                   1275:             fprintf( stderr, "  - Bearbeite WAVETABLE-IRQ\n" );
                   1276:             #endif
                   1277:             GUS_WorkOnVoices();
                   1278: 
                   1279:         }
                   1280: 
                   1281: 
                   1282:         if( ubIntArt & 4 )          // Timer 1?
                   1283:         {
                   1284:             #ifdef DEBUG
                   1285:             fprintf( stderr, "  - Bearbeite Timer 1-IRQ\n" );
                   1286:             #endif
                   1287: 
                   1288:             WriteGUSb( GUS_COMMAND, GUS_CMD_TIMERCTRL );
                   1289:             ubTemp = ReadGUSb( GUS_DATAHI );
                   1290: 
                   1291:             WriteGUSb( GUS_COMMAND, GUS_CMD_TIMERCTRL );
                   1292:             WriteGUSb( GUS_DATAHI, ubTemp & (~4) );        // Timer 1 aus
                   1293:         }
                   1294: 
                   1295:         if( ubIntArt & 8 )          // Timer 2?
                   1296:         {
                   1297:             #ifdef DEBUG
                   1298:             fprintf( stderr, "  - Bearbeite Timer 2-IRQ\n" );
                   1299:             #endif
                   1300: 
                   1301:             WriteGUSb( GUS_COMMAND, GUS_CMD_TIMERCTRL );
                   1302:             ubTemp = ReadGUSb( GUS_DATAHI );
                   1303: 
                   1304:             WriteGUSb( GUS_COMMAND, GUS_CMD_TIMERCTRL );
                   1305:             WriteGUSb( GUS_DATAHI, ubTemp & (~8) );        // Timer 2 aus
                   1306:         }
                   1307:     }
                   1308: 
                   1309:     #ifdef DEBUG
                   1310:     fprintf( stderr, "- Interruptende\n\n" );
                   1311:     #endif
                   1312: 
                   1313:     if( ubGUSGF1Int > 7 )
                   1314:         outportb( 0xA0, 0x20 );
                   1315: 
                   1316:     outportb( 0x20, 0x20 );
                   1317: 
                   1318: }
                   1319: 
                   1320: 
                   1321: // Dummy-Routine zum erkennen des Programmendes
                   1322: 
                   1323: void GUS_DummyFunc( void )
                   1324: {
                   1325:     ;
                   1326: }
                   1327: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.