Annotation of hatari/src/midi.c, revision 1.1.1.4

1.1       root        1: /*
1.1.1.2   root        2:   Hatari - midi.c
1.1       root        3: 
1.1.1.2   root        4:   This file is distributed under the GNU Public License, version 2 or at
                      5:   your option any later version. Read the file gpl.txt for details.
                      6: 
                      7:   MIDI communication.
                      8:   Note that this code is far from being perfect. However, it is already
                      9:   enough to let some ST programs (e.g. the game Pirates!) use the host's midi
                     10:   system.
                     11: 
                     12:   TODO:
                     13:    - Midi input (??)
                     14:    - No exact timing yet: Sending MIDI data should probably rather be done
                     15:      with an "interrupt" from int.c (just like it is done by the code in
                     16:      ikbd.c).
                     17:    - Most bits in the ACIA's status + control registers are currently ignored.
                     18:    - Check when we have to clear the ACIA_SR_INTERRUPT_REQUEST bit in the
                     19:      ACIA status register (it is currently done when reading or writing to
                     20:      the data register, but probably it should rather be done when reading the
                     21:      status register?).
1.1       root       22: */
1.1.1.4 ! root       23: const char Midi_rcsid[] = "Hatari $Id: midi.c,v 1.7 2006/02/08 22:49:27 eerot Exp $";
1.1.1.2   root       24: 
                     25: #include <SDL_types.h>
1.1       root       26: 
                     27: #include "main.h"
1.1.1.2   root       28: #include "configuration.h"
1.1.1.3   root       29: #include "ioMem.h"
1.1.1.4 ! root       30: #include "m68000.h"
1.1.1.2   root       31: #include "mfp.h"
                     32: #include "midi.h"
                     33: 
                     34: 
                     35: #define ACIA_SR_INTERRUPT_REQUEST  0x80
                     36: 
                     37: 
                     38: #define MIDI_DEBUG 0
                     39: 
                     40: #if MIDI_DEBUG
                     41: #define Dprintf(a) printf a
                     42: #else
                     43: #define Dprintf(a)
                     44: #endif
                     45: 
                     46: 
                     47: static FILE *pMidiOutFileHandle = NULL;         /* Used for Midi output */
                     48: static Uint8 MidiControlRegister;
                     49: static Uint8 MidiStatusRegister;
                     50: 
                     51: 
                     52: /*-----------------------------------------------------------------------*/
                     53: /*
                     54:   Initialization: Open MIDI device.
                     55: */
                     56: void Midi_Init(void)
                     57: {
                     58:        MidiStatusRegister = 2;
                     59: 
                     60:        if (ConfigureParams.Midi.bEnableMidi)
                     61:        {
                     62:                /* Open MIDI file... */
                     63:                pMidiOutFileHandle = fopen(ConfigureParams.Midi.szMidiOutFileName, "wb");
                     64: 
                     65:                if (!pMidiOutFileHandle)
                     66:                {
                     67:                        fprintf(stderr, "Failed to open %s.\n", ConfigureParams.Midi.szMidiOutFileName);
                     68:                        ConfigureParams.Midi.bEnableMidi = FALSE;
                     69:                        return;
                     70:                }
                     71: 
                     72:                Dprintf(("Opened midi file %s.\n", ConfigureParams.Midi.szMidiOutFileName));
                     73:        }
                     74: }
                     75: 
                     76: 
                     77: /*-----------------------------------------------------------------------*/
                     78: /*
                     79:   Close MIDI device.
                     80: */
                     81: void Midi_UnInit(void)
                     82: {
                     83:        if (pMidiOutFileHandle)
                     84:        {
                     85:                /* Close MIDI file... */
                     86:                fclose(pMidiOutFileHandle);
                     87:                pMidiOutFileHandle = NULL;
                     88:        }
                     89: }
                     90: 
                     91: 
                     92: /*-----------------------------------------------------------------------*/
                     93: /*
                     94:   Read MIDI status register ($FFFC04).
                     95: */
1.1.1.3   root       96: void Midi_Control_ReadByte(void)
1.1.1.2   root       97: {
                     98:        /* Dprintf(("Midi_ReadControl : $%x.\n", MidiStatusRegister)); */
                     99: 
1.1.1.4 ! root      100:        /* ACIA registers need wait states - but the value seems to vary in certain cases */
        !           101:        M68000_WaitState(8);
        !           102: 
1.1.1.3   root      103:        IoMem[0xfffc04] = MidiStatusRegister;
1.1.1.2   root      104: }
                    105: 
                    106: 
                    107: /*-----------------------------------------------------------------------*/
                    108: /*
                    109:   Read MIDI data register ($FFFC06).
                    110: */
1.1.1.3   root      111: void Midi_Data_ReadByte(void)
1.1.1.2   root      112: {
                    113:        Dprintf(("Midi_ReadData : $%x.\n", 1));
                    114: 
1.1.1.4 ! root      115:        /* ACIA registers need wait states - but the value seems to vary in certain cases */
        !           116:        M68000_WaitState(8);
        !           117: 
1.1.1.2   root      118:        MidiStatusRegister &= ~ACIA_SR_INTERRUPT_REQUEST;
                    119: 
1.1.1.3   root      120:        IoMem[0xfffc06] = 1;        /* Should be this? */
1.1.1.2   root      121: }
                    122: 
1.1       root      123: 
                    124: /*-----------------------------------------------------------------------*/
                    125: /*
1.1.1.2   root      126:   Write to MIDI control register ($FFFC04).
1.1       root      127: */
1.1.1.3   root      128: void Midi_Control_WriteByte(void)
1.1.1.2   root      129: {
1.1.1.4 ! root      130:        /* ACIA registers need wait states - but the value seems to vary in certain cases */
        !           131:        M68000_WaitState(8);
        !           132: 
1.1.1.3   root      133:        MidiControlRegister = IoMem[0xfffc04];
1.1.1.2   root      134: 
1.1.1.3   root      135:        Dprintf(("Midi_WriteControl($%x)\n", MidiControlRegister));
1.1.1.2   root      136: 
                    137:        /* Do we need to generate a transfer interrupt? */
                    138:        if ((MidiControlRegister & 0xA0) == 0xA0)
                    139:        {
                    140:                Dprintf(("WriteControl: Transfer interrupt!\n"));
                    141: 
                    142:                /* Acknowledge in MFP circuit, pass bit,enable,pending */
                    143:                MFP_InputOnChannel(MFP_ACIA_BIT, MFP_IERB, &MFP_IPRB);
                    144: 
                    145:                MidiStatusRegister |= ACIA_SR_INTERRUPT_REQUEST;
                    146:        }
                    147: }
                    148: 
                    149: 
                    150: /*-----------------------------------------------------------------------*/
                    151: /*
                    152:   Write to MIDI data register ($FFFC06).
                    153: */
1.1.1.3   root      154: void Midi_Data_WriteByte(void)
1.1.1.2   root      155: {
1.1.1.4 ! root      156:        Uint8 dataByte;
        !           157: 
        !           158:        /* ACIA registers need wait states - but the value seems to vary in certain cases */
        !           159:        M68000_WaitState(8);
        !           160: 
        !           161:        dataByte = IoMem[0xfffc06];
1.1.1.3   root      162: 
1.1.1.2   root      163:        Dprintf(("Midi_WriteData($%x)\n", dataByte));
                    164: 
                    165:        MidiStatusRegister &= ~ACIA_SR_INTERRUPT_REQUEST;
                    166: 
                    167:        if (!ConfigureParams.Midi.bEnableMidi)
                    168:                return;
                    169: 
                    170:        if (pMidiOutFileHandle)
                    171:        {
                    172:                int ret;
                    173:                
                    174:                /* Write the character to the output file: */
                    175:                ret = fputc(dataByte, pMidiOutFileHandle);
                    176:                
                    177:                /* If there was an error then stop the midi emulation */
                    178:                if (ret == EOF)
                    179:                {
                    180:                        Midi_UnInit();
                    181:                        return;
                    182:                }
                    183: 
                    184:                /* Do not queue the midi data! */
                    185:                fflush(pMidiOutFileHandle);
                    186:        }
                    187: 
                    188:        /* Do we need to generate a transfer interrupt? */
                    189:        if ((MidiControlRegister & 0xA0) == 0xA0)
                    190:        {
                    191:                Dprintf(("WriteData: Transfer interrupt!\n"));
                    192: 
                    193:                /* Acknowledge in MFP circuit, pass bit,enable,pending */
                    194:                MFP_InputOnChannel(MFP_ACIA_BIT, MFP_IERB, &MFP_IPRB);
                    195: 
                    196:                MidiStatusRegister |= ACIA_SR_INTERRUPT_REQUEST;
                    197:        }
                    198: }

unix.superglobalmegacorp.com

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