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

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++ )
1.1.1.2 ! root      178:        inportb( uwGUSPort+GUS_DATAHI );
1.1       root      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:     {
1.1.1.2 ! root      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
1.1       root      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 ?
1.1.1.2 ! root      270:        return;             // Nein, dann Ende
1.1       root      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:     {
1.1.1.2 ! root      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;
1.1       root      305:     }
                    306: 
                    307:     if( ubGUSDMA1 == ubGUSDMA2 )    // Gleichen DMA fuer beides ?
1.1.1.2 ! root      308:        nDMA = (nDMA&0x3)|(1<<6);
1.1       root      309: 
                    310: 
                    311:     // Interrupt der GUS setzen
                    312: 
                    313:     nInt=0;
                    314:     for( j=0; j<2; j++ )
                    315:     {
1.1.1.2 ! root      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;
1.1       root      342:     }
                    343: 
                    344:     if( ubGUSGF1Int == ubGUSMIDIInt )
1.1.1.2 ! root      345:        nInt = (nInt&0x3)|(1<<6);
1.1       root      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 )
1.1.1.2 ! root      397:        return 0;
1.1       root      398: 
                    399: 
                    400:     if( (*dspbits != 8 ) && (*dspbits != 16 ) )
                    401:     {
1.1.1.2 ! root      402:        printf( "%d bits are not supported on the GUS !\n", dspbits );
        !           403:        return 0;
1.1       root      404:     }
                    405: 
                    406: 
                    407:     ubGUSUsedBits = (*dspbits==8)?0:4;
                    408: 
                    409:     if( (*rate < 1000) || (*rate > 44100 ))
                    410:     {
1.1.1.2 ! root      411:        fprintf( stderr, "%dHz are not supported on the GUS !\n", *rate );
        !           412:        return 0;
1.1       root      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)  )
1.1.1.2 ! root      433:        return 0;
1.1       root      434: 
                    435:     ubGUSDMA1 = (UBYTE)atol( pz+1 );
                    436:     pz = strchr( pz+1, ',' );
                    437:     if( pz == 0 )
1.1.1.2 ! root      438:        return 0;
1.1       root      439: 
                    440:     ubGUSDMA2 = (UBYTE)atol( pz+1 );
                    441: 
                    442:     pz = strchr( pz+1, ',' );
                    443:     if( pz == 0 )
1.1.1.2 ! root      444:        return 0;
1.1       root      445: 
                    446:     ubGUSGF1Int = (UBYTE)atol( pz+1 );
                    447:     if( ubGUSGF1Int == 0 )
1.1.1.2 ! root      448:        return 0;
1.1       root      449: 
                    450:     pz = strchr( pz+1, ',' );
                    451:     if( pz == 0 )
1.1.1.2 ! root      452:        return 0;
1.1       root      453: 
                    454:     ubGUSMIDIInt = (UBYTE)atol( pz+1 );
                    455:     if( ubGUSMIDIInt == 0 )
1.1.1.2 ! root      456:        return 0;
1.1       root      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:     {
1.1.1.2 ! root      482:        fprintf( stderr, "Cannot allocate soundbuffer !\n" );
        !           483:        return 0;
1.1       root      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 ?
1.1.1.2 ! root      504:        return 0;
1.1       root      505: 
                    506:     // GUS-RAM loeschen
                    507: 
                    508:     j=-1;
                    509:     for( i=0; i<(int)(ulDMABufMaxSize*2+1000); i++ )
                    510:     {
1.1.1.2 ! root      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:        }
1.1       root      518: 
1.1.1.2 ! root      519:        WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMIOADRLO );
        !           520:        WriteGUSw( GUS_DATALO,  LSW( i ) );
1.1       root      521: 
1.1.1.2 ! root      522:        WriteGUSb( GUS_DRAM, 0 );
1.1       root      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:     {
1.1.1.2 ! root      533:        fprintf( stderr, "Cannot allocate protected mode wrapper for GUS interrupt!\n");
        !           534:        if( dmabufadr != 0 )
        !           535:            _go32_dpmi_free_dos_memory( &dma_mem );
1.1       root      536: 
1.1.1.2 ! root      537:        return 0;
1.1       root      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:     {
1.1.1.2 ! root      551:        outportb( 0xA1, inportb( 0xA1 ) & ~(1 << ( ubGUSGF1Int-8 ) ) );
        !           552:        outportb( 0xA0, 0x20 );
1.1       root      553:     }
                    554:     else
                    555:     {
1.1.1.2 ! root      556:        outportb( 0x21, inportb( 0x21 ) & ~(1 << ubGUSGF1Int));
        !           557:        outportb( 0x20, 0x20 );
1.1       root      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:     {
1.1.1.2 ! root      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 ) );
1.1       root      591:     }
                    592:     else
                    593:     {
1.1.1.2 ! root      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 ) ) );
1.1       root      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:     {
1.1.1.2 ! root      654:        do
        !           655:        {
        !           656:            delay( 10 );
        !           657:        }
        !           658:        while( bDMAInProgress == TRUE );
1.1       root      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 )
1.1.1.2 ! root      684:        outportb (0xA1, inportb(0xA1) | (1 << (ubGUSGF1Int-8)));
1.1       root      685:     else
1.1.1.2 ! root      686:        outportb (0x21, inportb(0x21) | (1 << ubGUSGF1Int));
1.1       root      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 )
1.1.1.2 ! root      695:        free( pGUSBuffer );
1.1       root      696: 
                    697:     if( dmabufadr != 0 )
1.1.1.2 ! root      698:        _go32_dpmi_free_dos_memory( &dma_mem );  // Speicher fuer DMA freigeben
1.1       root      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:     {
1.1.1.2 ! root      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:        }
1.1       root      733: 
                    734:     } */
                    735: 
                    736:     disable();
                    737: 
                    738:     // Daten in den GUS-Buffer kopieren
                    739: 
                    740:     if( size+ulBytesInBuffer>ulGUSSndBufSize )
                    741:     {
1.1.1.2 ! root      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:        }
1.1       root      752: 
                    753:     }
                    754:     else
                    755:     {
1.1.1.2 ! root      756:        // GUS-Buffer fuellen
1.1       root      757: 
1.1.1.2 ! root      758:        // Koennen wir auf einmal kopieren ?
1.1       root      759: 
1.1.1.2 ! root      760:        i = ulGUSSndBufSize-nGUSBufferWriteIndex;
        !           761:        if( i < size )
        !           762:        {
        !           763:            memcpy( pGUSBuffer+nGUSBufferWriteIndex, buf, i );
1.1       root      764: 
1.1.1.2 ! root      765:            memcpy( pGUSBuffer, ((UBYTE*)buf)+i, size-i );
1.1       root      766: 
1.1.1.2 ! root      767:        }
        !           768:        else
        !           769:        {
        !           770:            memcpy( pGUSBuffer+nGUSBufferWriteIndex, buf, size );
        !           771:        }
1.1       root      772: 
1.1.1.2 ! root      773:        nGUSBufferWriteIndex = (nGUSBufferWriteIndex+size)&(ulGUSSndBufSize-1);
1.1       root      774: 
1.1.1.2 ! root      775:        ulBytesInBuffer += size;
1.1       root      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:     {
1.1.1.2 ! root      805:        fprintf( stderr, "Error in StartDMA, DMA already im progress !\n" );
        !           806:        return;
1.1       root      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
1.1.1.2 ! root      818:        pDMABuf = dmabufadr;
1.1       root      819: 
1.1.1.2 ! root      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:        }
1.1       root      830: 
                    831:     }
                    832:     else
                    833:     {
1.1.1.2 ! root      834:        if( ulBytesInBuffer >= ulDMABufMaxSize )    // Sind mehr Daten da, als
        !           835:        {                                           // der Puffer gross ist ?
1.1       root      836: 
1.1.1.2 ! root      837:            pDMABuf = dmabufadr;                    // Ja, DMA-Puffer vollmachen
1.1       root      838: 
1.1.1.2 ! root      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:            }
1.1       root      877: 
                    878: 
1.1.1.2 ! root      879:            ulBytesInBuffer = 0;
        !           880:        }
1.1       root      881: 
                    882:     }
                    883: 
                    884: 
                    885:     if( bLoop == TRUE ) // Byte/Word kopieren, um das Geklicke zu verhindern
                    886:     {
                    887: 
1.1.1.2 ! root      888:        if( ubGUSUsedBits == 0 )    // 8 Bit ?
        !           889:        {
1.1       root      890: 
1.1.1.2 ! root      891:            WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMIOADRHI );
        !           892:            WriteGUSw( GUS_DATALO, MSW( ulPosInGUSRAM-ulDMABufMaxSize-1 ) );
1.1       root      893: 
1.1.1.2 ! root      894:            WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMIOADRLO );
        !           895:            WriteGUSw( GUS_DATALO, LSW( ulPosInGUSRAM-ulDMABufMaxSize-1 ) );
1.1       root      896: 
1.1.1.2 ! root      897:            WriteGUSb( GUS_DRAM, _farnspeekb( dmabufadr+ulDMABufMaxSize-1 )+0x80 );
1.1       root      898: 
1.1.1.2 ! root      899:        }
        !           900:        else
        !           901:        {
        !           902:            WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMIOADRHI );
        !           903:            WriteGUSw( GUS_DATALO, MSW( ulPosInGUSRAM-ulDMABufMaxSize-2 ) );
1.1       root      904: 
1.1.1.2 ! root      905:            WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMIOADRLO );
        !           906:            WriteGUSw( GUS_DATALO, LSW( ulPosInGUSRAM-ulDMABufMaxSize-2 ) );
1.1       root      907: 
1.1.1.2 ! root      908:            WriteGUSb( GUS_DRAM, _farnspeekb( dmabufadr+ulDMABufMaxSize-2 ) );
1.1       root      909: 
1.1.1.2 ! root      910:            WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMIOADRHI );
        !           911:            WriteGUSw( GUS_DATALO, MSW( ulPosInGUSRAM-ulDMABufMaxSize-1 ) );
1.1       root      912: 
1.1.1.2 ! root      913:            WriteGUSb( GUS_COMMAND, GUS_CMD_DRAMIOADRLO );
        !           914:            WriteGUSw( GUS_DATALO, LSW( ulPosInGUSRAM-ulDMABufMaxSize-1 ) );
1.1       root      915: 
1.1.1.2 ! root      916:            WriteGUSb( GUS_DRAM, _farnspeekb( dmabufadr+ulDMABufMaxSize-1 ) );
1.1       root      917: 
1.1.1.2 ! root      918:        }
1.1       root      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 )
1.1.1.2 ! root      929:        WriteGUSw( GUS_DATALO, CONVTO16B(ulPosInGUSRAM>>4) ); // Adresse>>4 !!!!
1.1       root      930:     else
1.1.1.2 ! root      931:        WriteGUSw( GUS_DATALO, (UWORD)(ulPosInGUSRAM>>4) ); // Adresse>>4 !!!!
1.1       root      932: 
                    933:     if( ubGUSUsedBits == 0 )
                    934:     {                               // 8 Bit
1.1.1.2 ! root      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:        }
1.1       root      946:     }
                    947:     else
                    948:     {                       // 16 Bit
1.1.1.2 ! root      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:        }
1.1       root      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: 
1.1.1.2 ! root      990:        WriteGUSb( GUS_COMMAND, GUS_CMD_IRQSOURCER );   // IRQ-Art holen
        !           991:        ubIntArt = ReadGUSb( GUS_DATAHI );
1.1       root      992: 
1.1.1.2 ! root      993:        nVoice = ubIntArt & 0x1f;
        !           994:        nVoiceBit = ((ULONG)1)<<((ULONG)nVoice);
1.1       root      995: 
1.1.1.2 ! root      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 );
1.1       root     1144: 
                   1145: 
1.1.1.2 ! root     1146:                WriteGUSb( GUS_COMMAND, GUS_CMD_VOLUMECTRLW );
        !          1147:                WriteGUSb( GUS_DATAHI, (ubTemp2 & (~32)) | 3 );
1.1       root     1148: 
1.1.1.2 ! root     1149:            }
1.1       root     1150: 
1.1.1.2 ! root     1151:        }
1.1       root     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 )
1.1.1.2 ! root     1176:        return;
1.1       root     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: 
1.1.1.2 ! root     1185:        ubIntArt = ReadGUSb( GUS_IRQSTATE );
1.1       root     1186: 
1.1.1.2 ! root     1187:        #ifdef DEBUG
        !          1188:        fprintf( stderr, "  IRQ-Status (2x6): $%X\n", ubIntArt );
        !          1189:        #endif
1.1       root     1190: 
                   1191: 
1.1.1.2 ! root     1192:        if( ubIntArt == 0 )         // Fertig ?
        !          1193:            break;
1.1       root     1194: 
1.1.1.2 ! root     1195:        if( ubIntArt & 128 )        // TC-IRQ ?
        !          1196:        {
1.1       root     1197: 
1.1.1.2 ! root     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
1.1       root     1204: 
1.1.1.2 ! root     1205:                bDMAInProgress = FALSE;
1.1       root     1206: 
1.1.1.2 ! root     1207:            }
1.1       root     1208: 
1.1.1.2 ! root     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
1.1       root     1215: 
1.1.1.2 ! root     1216:            }
1.1       root     1217: 
1.1.1.2 ! root     1218:        }
1.1       root     1219: 
1.1.1.2 ! root     1220:        if( ubIntArt & 3 )
        !          1221:        {
        !          1222:            #ifdef DEBUG
        !          1223:            fprintf( stderr, "  - Bearbeite MIDI-IRQ\n" );
        !          1224:            #endif
1.1       root     1225: 
1.1.1.2 ! root     1226:        }
1.1       root     1227: 
1.1.1.2 ! root     1228:        if( ubIntArt & 64 )
        !          1229:        {
        !          1230:            #ifdef DEBUG
        !          1231:            fprintf( stderr, "  - Bearbeite VOLUME-IRQ\n" );
        !          1232:            #endif
        !          1233:            GUS_WorkOnVoices();
1.1       root     1234: 
                   1235: 
1.1.1.2 ! root     1236:        }
1.1       root     1237: 
1.1.1.2 ! root     1238:        if( ubIntArt & 32 )
        !          1239:        {
        !          1240:            #ifdef DEBUG
        !          1241:            fprintf( stderr, "  - Bearbeite WAVETABLE-IRQ\n" );
        !          1242:            #endif
        !          1243:            GUS_WorkOnVoices();
1.1       root     1244: 
1.1.1.2 ! root     1245:        }
1.1       root     1246: 
                   1247: 
1.1.1.2 ! root     1248:        if( ubIntArt & 4 )          // Timer 1?
        !          1249:        {
        !          1250:            #ifdef DEBUG
        !          1251:            fprintf( stderr, "  - Bearbeite Timer 1-IRQ\n" );
        !          1252:            #endif
1.1       root     1253: 
1.1.1.2 ! root     1254:            WriteGUSb( GUS_COMMAND, GUS_CMD_TIMERCTRL );
        !          1255:            ubTemp = ReadGUSb( GUS_DATAHI );
1.1       root     1256: 
1.1.1.2 ! root     1257:            WriteGUSb( GUS_COMMAND, GUS_CMD_TIMERCTRL );
        !          1258:            WriteGUSb( GUS_DATAHI, ubTemp & (~4) );        // Timer 1 aus
        !          1259:        }
1.1       root     1260: 
1.1.1.2 ! root     1261:        if( ubIntArt & 8 )          // Timer 2?
        !          1262:        {
        !          1263:            #ifdef DEBUG
        !          1264:            fprintf( stderr, "  - Bearbeite Timer 2-IRQ\n" );
        !          1265:            #endif
1.1       root     1266: 
1.1.1.2 ! root     1267:            WriteGUSb( GUS_COMMAND, GUS_CMD_TIMERCTRL );
        !          1268:            ubTemp = ReadGUSb( GUS_DATAHI );
1.1       root     1269: 
1.1.1.2 ! root     1270:            WriteGUSb( GUS_COMMAND, GUS_CMD_TIMERCTRL );
        !          1271:            WriteGUSb( GUS_DATAHI, ubTemp & (~8) );        // Timer 2 aus
        !          1272:        }
1.1       root     1273:     }
                   1274: 
                   1275:     #ifdef DEBUG
                   1276:     fprintf( stderr, "- Interruptende\n\n" );
                   1277:     #endif
                   1278: 
                   1279:     if( ubGUSGF1Int > 7 )
1.1.1.2 ! root     1280:        outportb( 0xA0, 0x20 );
1.1       root     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.