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

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.5 ! root       23: const char Midi_rcsid[] = "Hatari $Id: midi.c,v 1.9 2007/02/25 21:20:10 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"
1.1.1.5 ! root       33: #include "file.h"
1.1.1.2   root       34: 
                     35: 
                     36: #define ACIA_SR_INTERRUPT_REQUEST  0x80
                     37: 
                     38: #define MIDI_DEBUG 0
                     39: #if MIDI_DEBUG
                     40: #define Dprintf(a) printf a
                     41: #else
                     42: #define Dprintf(a)
                     43: #endif
                     44: 
                     45: 
                     46: static FILE *pMidiOutFileHandle = NULL;         /* Used for Midi output */
                     47: static Uint8 MidiControlRegister;
                     48: static Uint8 MidiStatusRegister;
                     49: 
                     50: 
                     51: /*-----------------------------------------------------------------------*/
1.1.1.5 ! root       52: /**
        !            53:  * Initialization: Open MIDI device.
        !            54:  */
1.1.1.2   root       55: void Midi_Init(void)
                     56: {
                     57:        MidiStatusRegister = 2;
                     58: 
1.1.1.5 ! root       59:        if (!ConfigureParams.Midi.bEnableMidi)
        !            60:                return;
1.1.1.2   root       61: 
1.1.1.5 ! root       62:        /* Open MIDI file... */
        !            63:        pMidiOutFileHandle = File_Open(ConfigureParams.Midi.szMidiOutFileName, "wb");
        !            64:        if (!pMidiOutFileHandle)
        !            65:        {
        !            66:                ConfigureParams.Midi.bEnableMidi = FALSE;
        !            67:                return;
1.1.1.2   root       68:        }
1.1.1.5 ! root       69:        Dprintf(("Opened midi file '%s'.\n", ConfigureParams.Midi.szMidiOutFileName));
1.1.1.2   root       70: }
                     71: 
                     72: 
                     73: /*-----------------------------------------------------------------------*/
1.1.1.5 ! root       74: /**
        !            75:  * Close MIDI device.
        !            76:  */
1.1.1.2   root       77: void Midi_UnInit(void)
                     78: {
1.1.1.5 ! root       79:        pMidiOutFileHandle = File_Close(pMidiOutFileHandle);
1.1.1.2   root       80: }
                     81: 
                     82: 
                     83: /*-----------------------------------------------------------------------*/
1.1.1.5 ! root       84: /**
        !            85:  * Read MIDI status register ($FFFC04).
        !            86:  */
1.1.1.3   root       87: void Midi_Control_ReadByte(void)
1.1.1.2   root       88: {
                     89:        /* Dprintf(("Midi_ReadControl : $%x.\n", MidiStatusRegister)); */
                     90: 
1.1.1.4   root       91:        /* ACIA registers need wait states - but the value seems to vary in certain cases */
                     92:        M68000_WaitState(8);
                     93: 
1.1.1.3   root       94:        IoMem[0xfffc04] = MidiStatusRegister;
1.1.1.2   root       95: }
                     96: 
                     97: 
                     98: /*-----------------------------------------------------------------------*/
1.1.1.5 ! root       99: /**
        !           100:  * Read MIDI data register ($FFFC06).
        !           101:  */
1.1.1.3   root      102: void Midi_Data_ReadByte(void)
1.1.1.2   root      103: {
                    104:        Dprintf(("Midi_ReadData : $%x.\n", 1));
                    105: 
1.1.1.4   root      106:        /* ACIA registers need wait states - but the value seems to vary in certain cases */
                    107:        M68000_WaitState(8);
                    108: 
1.1.1.2   root      109:        MidiStatusRegister &= ~ACIA_SR_INTERRUPT_REQUEST;
                    110: 
1.1.1.3   root      111:        IoMem[0xfffc06] = 1;        /* Should be this? */
1.1.1.2   root      112: }
                    113: 
1.1       root      114: 
                    115: /*-----------------------------------------------------------------------*/
1.1.1.5 ! root      116: /**
        !           117:  * Write to MIDI control register ($FFFC04).
        !           118:  */
1.1.1.3   root      119: void Midi_Control_WriteByte(void)
1.1.1.2   root      120: {
1.1.1.4   root      121:        /* ACIA registers need wait states - but the value seems to vary in certain cases */
                    122:        M68000_WaitState(8);
                    123: 
1.1.1.3   root      124:        MidiControlRegister = IoMem[0xfffc04];
1.1.1.2   root      125: 
1.1.1.3   root      126:        Dprintf(("Midi_WriteControl($%x)\n", MidiControlRegister));
1.1.1.2   root      127: 
                    128:        /* Do we need to generate a transfer interrupt? */
                    129:        if ((MidiControlRegister & 0xA0) == 0xA0)
                    130:        {
                    131:                Dprintf(("WriteControl: Transfer interrupt!\n"));
                    132: 
                    133:                /* Acknowledge in MFP circuit, pass bit,enable,pending */
                    134:                MFP_InputOnChannel(MFP_ACIA_BIT, MFP_IERB, &MFP_IPRB);
                    135: 
                    136:                MidiStatusRegister |= ACIA_SR_INTERRUPT_REQUEST;
                    137:        }
                    138: }
                    139: 
                    140: 
                    141: /*-----------------------------------------------------------------------*/
1.1.1.5 ! root      142: /**
        !           143:  * Write to MIDI data register ($FFFC06).
        !           144:  */
1.1.1.3   root      145: void Midi_Data_WriteByte(void)
1.1.1.2   root      146: {
1.1.1.4   root      147:        Uint8 dataByte;
                    148: 
                    149:        /* ACIA registers need wait states - but the value seems to vary in certain cases */
                    150:        M68000_WaitState(8);
                    151: 
                    152:        dataByte = IoMem[0xfffc06];
1.1.1.3   root      153: 
1.1.1.2   root      154:        Dprintf(("Midi_WriteData($%x)\n", dataByte));
                    155: 
                    156:        MidiStatusRegister &= ~ACIA_SR_INTERRUPT_REQUEST;
                    157: 
                    158:        if (!ConfigureParams.Midi.bEnableMidi)
                    159:                return;
                    160: 
                    161:        if (pMidiOutFileHandle)
                    162:        {
                    163:                int ret;
                    164:                
                    165:                /* Write the character to the output file: */
                    166:                ret = fputc(dataByte, pMidiOutFileHandle);
                    167:                
                    168:                /* If there was an error then stop the midi emulation */
                    169:                if (ret == EOF)
                    170:                {
                    171:                        Midi_UnInit();
                    172:                        return;
                    173:                }
                    174: 
                    175:                /* Do not queue the midi data! */
                    176:                fflush(pMidiOutFileHandle);
                    177:        }
                    178: 
                    179:        /* Do we need to generate a transfer interrupt? */
                    180:        if ((MidiControlRegister & 0xA0) == 0xA0)
                    181:        {
                    182:                Dprintf(("WriteData: Transfer interrupt!\n"));
                    183: 
                    184:                /* Acknowledge in MFP circuit, pass bit,enable,pending */
                    185:                MFP_InputOnChannel(MFP_ACIA_BIT, MFP_IERB, &MFP_IPRB);
                    186: 
                    187:                MidiStatusRegister |= ACIA_SR_INTERRUPT_REQUEST;
                    188:        }
                    189: }

unix.superglobalmegacorp.com

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