|
|
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.2 ! root 23: char Midi_rcsid[] = "Hatari $Id: midi.c,v 1.4 2004/04/19 08:53:34 thothy Exp $"; ! 24: ! 25: #include <SDL_types.h> 1.1 root 26: 27: #include "main.h" 1.1.1.2 ! root 28: #include "configuration.h" ! 29: #include "mfp.h" ! 30: #include "midi.h" ! 31: ! 32: ! 33: #define ACIA_SR_INTERRUPT_REQUEST 0x80 ! 34: ! 35: ! 36: #define MIDI_DEBUG 0 ! 37: ! 38: #if MIDI_DEBUG ! 39: #define Dprintf(a) printf a ! 40: #else ! 41: #define Dprintf(a) ! 42: #endif ! 43: ! 44: ! 45: static FILE *pMidiOutFileHandle = NULL; /* Used for Midi output */ ! 46: static Uint8 MidiControlRegister; ! 47: static Uint8 MidiStatusRegister; ! 48: ! 49: ! 50: /*-----------------------------------------------------------------------*/ ! 51: /* ! 52: Initialization: Open MIDI device. ! 53: */ ! 54: void Midi_Init(void) ! 55: { ! 56: MidiStatusRegister = 2; ! 57: ! 58: if (ConfigureParams.Midi.bEnableMidi) ! 59: { ! 60: /* Open MIDI file... */ ! 61: pMidiOutFileHandle = fopen(ConfigureParams.Midi.szMidiOutFileName, "wb"); ! 62: ! 63: if (!pMidiOutFileHandle) ! 64: { ! 65: fprintf(stderr, "Failed to open %s.\n", ConfigureParams.Midi.szMidiOutFileName); ! 66: ConfigureParams.Midi.bEnableMidi = FALSE; ! 67: return; ! 68: } ! 69: ! 70: Dprintf(("Opened midi file %s.\n", ConfigureParams.Midi.szMidiOutFileName)); ! 71: } ! 72: } ! 73: ! 74: ! 75: /*-----------------------------------------------------------------------*/ ! 76: /* ! 77: Close MIDI device. ! 78: */ ! 79: void Midi_UnInit(void) ! 80: { ! 81: if (pMidiOutFileHandle) ! 82: { ! 83: /* Close MIDI file... */ ! 84: fclose(pMidiOutFileHandle); ! 85: pMidiOutFileHandle = NULL; ! 86: } ! 87: } ! 88: ! 89: ! 90: /*-----------------------------------------------------------------------*/ ! 91: /* ! 92: Read MIDI status register ($FFFC04). ! 93: */ ! 94: Uint8 Midi_ReadControl(void) ! 95: { ! 96: /* Dprintf(("Midi_ReadControl : $%x.\n", MidiStatusRegister)); */ ! 97: ! 98: return MidiStatusRegister; ! 99: } ! 100: ! 101: ! 102: /*-----------------------------------------------------------------------*/ ! 103: /* ! 104: Read MIDI data register ($FFFC06). ! 105: */ ! 106: Uint8 Midi_ReadData(void) ! 107: { ! 108: Dprintf(("Midi_ReadData : $%x.\n", 1)); ! 109: ! 110: MidiStatusRegister &= ~ACIA_SR_INTERRUPT_REQUEST; ! 111: ! 112: return 1; /* Should be this? */ ! 113: } ! 114: 1.1 root 115: 116: /*-----------------------------------------------------------------------*/ 117: /* 1.1.1.2 ! root 118: Write to MIDI control register ($FFFC04). 1.1 root 119: */ 1.1.1.2 ! root 120: void Midi_WriteControl(Uint8 controlByte) ! 121: { ! 122: Dprintf(("Midi_WriteControl($%x)\n", controlByte)); ! 123: ! 124: MidiControlRegister = controlByte; ! 125: ! 126: /* Do we need to generate a transfer interrupt? */ ! 127: if ((MidiControlRegister & 0xA0) == 0xA0) ! 128: { ! 129: Dprintf(("WriteControl: Transfer interrupt!\n")); ! 130: ! 131: /* Acknowledge in MFP circuit, pass bit,enable,pending */ ! 132: MFP_InputOnChannel(MFP_ACIA_BIT, MFP_IERB, &MFP_IPRB); ! 133: ! 134: MidiStatusRegister |= ACIA_SR_INTERRUPT_REQUEST; ! 135: } ! 136: } ! 137: ! 138: ! 139: /*-----------------------------------------------------------------------*/ ! 140: /* ! 141: Write to MIDI data register ($FFFC06). ! 142: */ ! 143: void Midi_WriteData(Uint8 dataByte) ! 144: { ! 145: Dprintf(("Midi_WriteData($%x)\n", dataByte)); ! 146: ! 147: MidiStatusRegister &= ~ACIA_SR_INTERRUPT_REQUEST; ! 148: ! 149: if (!ConfigureParams.Midi.bEnableMidi) ! 150: return; ! 151: ! 152: if (pMidiOutFileHandle) ! 153: { ! 154: int ret; ! 155: ! 156: /* Write the character to the output file: */ ! 157: ret = fputc(dataByte, pMidiOutFileHandle); ! 158: ! 159: /* If there was an error then stop the midi emulation */ ! 160: if (ret == EOF) ! 161: { ! 162: Midi_UnInit(); ! 163: return; ! 164: } ! 165: ! 166: /* Do not queue the midi data! */ ! 167: fflush(pMidiOutFileHandle); ! 168: } ! 169: ! 170: /* Do we need to generate a transfer interrupt? */ ! 171: if ((MidiControlRegister & 0xA0) == 0xA0) ! 172: { ! 173: Dprintf(("WriteData: Transfer interrupt!\n")); ! 174: ! 175: /* Acknowledge in MFP circuit, pass bit,enable,pending */ ! 176: MFP_InputOnChannel(MFP_ACIA_BIT, MFP_IERB, &MFP_IPRB); ! 177: ! 178: MidiStatusRegister |= ACIA_SR_INTERRUPT_REQUEST; ! 179: } ! 180: } ! 181:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.