Annotation of uae/src/od-dos/sound/gus.c, revision 1.1

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

unix.superglobalmegacorp.com

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