Skip to content

Commit

Permalink
Make MIDI card address flexible, add interrupts
Browse files Browse the repository at this point in the history
  • Loading branch information
mooinglemur committed Oct 2, 2024
1 parent d7b52ff commit 6214615
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 14 deletions.
3 changes: 3 additions & 0 deletions src/glue.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ extern bool has_via2;
extern uint32_t host_sample_rate;
extern bool enable_midline;

extern bool has_midi_card;
extern uint16_t midi_card_addr;

extern void machine_dump(const char* reason);
extern void machine_reset();
extern void machine_nmi();
Expand Down
36 changes: 32 additions & 4 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ bool enable_midline = false;
bool ym2151_irq_support = false;
char *cartridge_path = NULL;

bool has_midi_card = false;
uint16_t midi_card_addr;

bool using_hostfs = true;

uint8_t MHZ = 8;
Expand Down Expand Up @@ -528,6 +531,12 @@ usage()
printf("\tSuppress warning emitted when encountering a Rockwell extension on the 65C02\n");
printf("-longpwron\n");
printf("\tSimulate a long press of the power button at system power-on.\n");
printf("-midicard [<address>]\n");
printf("\tInstall a serial MIDI card at the specified address, or at $9F60 by default.\n");
printf("\tThe -sf2 option must be specified along with this option.\n");
printf("-sf2 <SoundFont filename>\n");
printf("\tInitialize MIDI synth with the specified SoundFont.\n");
printf("\tThe -midicard option must be specified along with this option.\n");
#ifdef TRACE
printf("-trace [<address>]\n");
printf("\tPrint instruction trace. Optionally, a trigger address\n");
Expand Down Expand Up @@ -633,6 +642,18 @@ main(int argc, char **argv)
prg_path = argv[0];
argc--;
argv++;
} else if (!strcmp(argv[0], "-midicard")) {
argc--;
argv++;
has_midi_card = true;
if (argc && argv[0][0] != '-') {
midi_card_addr = 0x9f00 | ((uint16_t)strtol(argv[0], NULL, 16) & 0xff);
midi_card_addr &= 0xfff0;
argc--;
argv++;
} else {
midi_card_addr = 0x9f60;
}
} else if (!strcmp(argv[0], "-sf2")) {
argc--;
argv++;
Expand Down Expand Up @@ -1100,9 +1121,16 @@ main(int argc, char **argv)
#endif
}

if (sf2_path) {
midi_init();
midi_load_sf2((uint8_t *)sf2_path);
if (sf2_path && has_midi_card) {
if (midi_card_addr < 0x9f60) {
fprintf(stderr, "Warning: Serial MIDI card address must be in the range of 9F60-9FF0\n");
} else {
midi_init();
midi_load_sf2((uint8_t *)sf2_path);
}
} else if (sf2_path || has_midi_card) {
fprintf(stderr, "Warning: -sf2 and -midicard must be specified together in order to enable the MIDI synth.\n");
has_midi_card = false;
}

if (cartridge_path) {
Expand Down Expand Up @@ -1634,7 +1662,7 @@ emulator_loop(void *param)
audio_render();
}

if (video_get_irq_out() || via1_irq() || (has_via2 && via2_irq()) || (ym2151_irq_support && YM_irq())) {
if (video_get_irq_out() || via1_irq() || (has_via2 && via2_irq()) || (ym2151_irq_support && YM_irq()) || (has_midi_card && midi_serial_irq())) {
// printf("IRQ!\n");
irq6502();
}
Expand Down
10 changes: 5 additions & 5 deletions src/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,12 +198,12 @@ real_read6502(uint16_t address, bool debugOn, int16_t bank)
return YM_read_status();
}
return 0x9f; // open bus read
} else if (address >= 0x9fc0 && address < 0x9fd0) {
// midi card
return midi_serial_read(address & 0xf, debugOn);
} else if (address >= 0x9fb0 && address < 0x9fc0) {
// emulator state
return emu_read(address & 0xf, debugOn);
} else if (has_midi_card && (address & 0xfff0) == midi_card_addr) {
// midi card
return midi_serial_read(address & 0xf, debugOn);
} else {
// future expansion
return 0x9f; // open bus read
Expand Down Expand Up @@ -278,11 +278,11 @@ write6502(uint16_t address, uint8_t value)
audio_render();
YM_write_reg(addr_ym, value);
}
} else if (address >= 0x9fc0 && address < 0x9fd0) {
midi_serial_write(address & 0xf, value);
} else if (address >= 0x9fb0 && address < 0x9fc0) {
// emulator state
emu_write(address & 0xf, value);
} else if (has_midi_card && (address & 0xfff0) == midi_card_addr) {
midi_serial_write(address & 0xf, value);
} else {
// future expansion
}
Expand Down
26 changes: 21 additions & 5 deletions src/midi.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ static bool serial_midi_mutexes_initialized = false;
#ifndef __EMSCRIPTEN__

int handle_midi_event(void* data, fluid_midi_event_t* event);
void midi_serial_iir_check(uint8_t sel);

static uint8_t sysex_buffer[1024];
static int sysex_bufptr;
Expand All @@ -143,7 +144,6 @@ static bool midi_initialized = false;

static fluid_settings_t* fl_settings;
static fluid_midi_driver_t* fl_mdriver;
//static fluid_audio_driver_t* fl_adriver;
static fluid_synth_t* fl_synth;
static int fl_sf2id;

Expand Down Expand Up @@ -270,15 +270,15 @@ void midi_init()
fl_mdriver = dl_new_fluid_midi_driver(fl_settings, handle_midi_event, &mregs[0]);

midi_initialized = true;
printf("Initialized MIDI synth.\n");
fprintf(stderr, "Initialized MIDI synth at $%04X.\n", midi_card_addr);
}

void midi_load_sf2(uint8_t* filename)
{
if (!midi_initialized) return;
fl_sf2id = dl_fs_sfload(fl_synth, (const char *)filename, true);
if (fl_sf2id == FLUID_FAILED) {
printf("Unable to load soundfont.\n");
fprintf(stderr, "Unable to load soundfont.\n");
}
}

Expand Down Expand Up @@ -365,7 +365,6 @@ void midi_synth_render(int16_t* buf, int len)

void midi_event_enqueue_byte(struct midi_serial_regs* mrp, uint8_t val)
{
mrp->in_midi_last_command = 0;
if (mrp->mfsz >= 256) return;
mrp->midi_event_fifo[mrp->mfsz++] = val;
}
Expand Down Expand Up @@ -434,8 +433,17 @@ int handle_midi_event(void* data, fluid_midi_event_t* event)
val = dl_fluid_midi_event_get_program(event);
midi_event_enqueue_short(mrp, cmd, val);
break;
case MIDI_SYNC:
case MIDI_TIME_CODE:
val = dl_fluid_midi_event_get_value(event);
midi_event_enqueue_short(mrp, type, val);
mrp->in_midi_last_command = 0;
break;
case MIDI_TUNE_REQUEST:
midi_event_enqueue_byte(mrp, type);
mrp->in_midi_last_command = 0;
break;
case MIDI_SYNC:
case MIDI_TICK:
case MIDI_START:
case MIDI_CONTINUE:
case MIDI_STOP:
Expand Down Expand Up @@ -614,6 +622,7 @@ void midi_serial_step(int clocks)
pthread_mutex_unlock(&mregs[sel].fifo_mutex);
mregs[sel].clock += 0x1000000LL;
}
midi_serial_iir_check(sel);
}
}

Expand Down Expand Up @@ -916,3 +925,10 @@ void midi_serial_write(uint8_t reg, uint8_t val)
break;
}
}

bool midi_serial_irq(void)
{
bool uart0int = (mregs[0].iir & 1) == 0 && mregs[0].mcr_out2;
bool uart1int = (mregs[1].iir & 1) == 0 && mregs[1].mcr_out2;
return (uart0int | uart1int);
}
1 change: 1 addition & 0 deletions src/midi.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ uint8_t midi_serial_read(uint8_t reg, bool debugOn);
void midi_serial_write(uint8_t reg, uint8_t val);
void midi_load_sf2(uint8_t* filename);
void midi_synth_render(int16_t* buf, int len);
bool midi_serial_irq(void);

0 comments on commit 6214615

Please sign in to comment.