diff --git a/src/CPU/x86_ops_mmx_mov.h b/src/CPU/x86_ops_mmx_mov.h index 8cc0c8e26..d96df747b 100644 --- a/src/CPU/x86_ops_mmx_mov.h +++ b/src/CPU/x86_ops_mmx_mov.h @@ -136,7 +136,7 @@ static int opMOVQ_mm_q_a16(uint32_t fetchdat) else { CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); - writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; + writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1; CLOCK_CYCLES(2); } return 0; diff --git a/src/SOUND/midi_fluidsynth.c b/src/SOUND/midi_fluidsynth.c index 453997065..7f4122d68 100644 --- a/src/SOUND/midi_fluidsynth.c +++ b/src/SOUND/midi_fluidsynth.c @@ -15,7 +15,8 @@ #include "midi.h" #include "sound.h" -#define RENDER_RATE 30 +#define RENDER_RATE 100 +#define BUFFER_SEGMENTS 10 extern void givealbuffer_midi(void *buf, uint32_t size); extern void pclog(const char *format, ...); @@ -111,9 +112,41 @@ void fluidsynth_poll(void) static void fluidsynth_thread(void *param) { fluidsynth_t* data = (fluidsynth_t*)param; + int buf_pos = 0; + int buf_size = data->buf_size / BUFFER_SEGMENTS; while (1) { thread_wait_event(data->event, -1); + if (sound_is_float) + { + float *buf = (float*)((uint8_t*)data->buffer + buf_pos); + memset(buf, 0, buf_size); + if (data->synth) + f_fluid_synth_write_float(data->synth, buf_size/(2 * sizeof(float)), buf, 0, 2, buf, 1, 2); + buf_pos += buf_size; + if (buf_pos >= data->buf_size) + { + if (soundon) + givealbuffer_midi(data->buffer, data->buf_size / sizeof(float)); + buf_pos = 0; + } + } + else + { + int16_t *buf = (int16_t*)((uint8_t*)data->buffer_int16 + buf_pos); + memset(buf, 0, buf_size); + if (data->synth) + f_fluid_synth_write_s16(data->synth, buf_size/(2 * sizeof(int16_t)), buf, 0, 2, buf, 1, 2); + buf_pos += buf_size; + if (buf_pos >= data->buf_size) + { + if (soundon) + givealbuffer_midi(data->buffer_int16, data->buf_size / sizeof(int16_t)); + buf_pos = 0; + } + } + +#if 0 if (sound_is_float) { memset(data->buffer, 0, data->buf_size * sizeof(float)); @@ -130,6 +163,7 @@ static void fluidsynth_thread(void *param) if (soundon) givealbuffer_midi(data->buffer_int16, data->buf_size); } +#endif } } @@ -253,16 +287,17 @@ void* fluidsynth_init(void) double samplerate; f_fluid_settings_getnum(data->settings, "synth.sample-rate", &samplerate); data->samplerate = (int)samplerate; - data->buf_size = data->samplerate/RENDER_RATE*2; if (sound_is_float) { - data->buffer = malloc(data->buf_size * sizeof(float)); + data->buf_size = (data->samplerate/RENDER_RATE)*2*sizeof(float)*BUFFER_SEGMENTS; + data->buffer = malloc(data->buf_size); data->buffer_int16 = NULL; } else { + data->buf_size = (data->samplerate/RENDER_RATE)*2*sizeof(int16_t)*BUFFER_SEGMENTS; data->buffer = NULL; - data->buffer_int16 = malloc(data->buf_size * sizeof(int16_t)); + data->buffer_int16 = malloc(data->buf_size); } data->event = thread_create_event(); data->thread_h = thread_create(fluidsynth_thread, data); @@ -299,11 +334,13 @@ void fluidsynth_close(void* p) if (data->buffer) { free(data->buffer); + data->buffer = NULL; } if (data->buffer_int16) { free(data->buffer_int16); + data->buffer_int16 = NULL; } /* Unload the DLL if possible. */ diff --git a/src/SOUND/midi_mt32.c b/src/SOUND/midi_mt32.c index ddf561ee0..2e81c6265 100644 --- a/src/SOUND/midi_mt32.c +++ b/src/SOUND/midi_mt32.c @@ -83,7 +83,8 @@ int cm32l_available() static thread_t *thread_h = NULL; static event_t *event = NULL; -#define RENDER_RATE 30 +#define RENDER_RATE 100 +#define BUFFER_SEGMENTS 10 static uint32_t samplerate = 44100; static int buf_size = 0; @@ -115,22 +116,37 @@ extern int soundon; static void mt32_thread(void *param) { + int buf_pos = 0; + int bsize = buf_size / BUFFER_SEGMENTS; while (1) { thread_wait_event(event, -1); + if (sound_is_float) { - memset(buffer, 0, buf_size * sizeof(float)); - mt32_stream(buffer, (samplerate/RENDER_RATE)); - if (soundon) - givealbuffer_midi(buffer, buf_size); + float *buf = (float *) ((uint8_t*)buffer + buf_pos); + memset(buf, 0, bsize); + mt32_stream(buf, bsize / (2 * sizeof(float))); + buf_pos += bsize; + if (buf_pos >= buf_size) + { + if (soundon) + givealbuffer_midi(buffer, buf_size / sizeof(float)); + buf_pos = 0; + } } else { - memset(buffer_int16, 0, buf_size * sizeof(int16_t)); - mt32_stream_int16(buffer_int16, (samplerate/RENDER_RATE)); - if (soundon) - givealbuffer_midi(buffer_int16, buf_size); + int16_t *buf = (int16_t *) ((uint8_t*)buffer_int16 + buf_pos); + memset(buf, 0, bsize); + mt32_stream_int16(buf, bsize / (2 * sizeof(int16_t))); + buf_pos += bsize; + if (buf_pos >= buf_size) + { + if (soundon) + givealbuffer_midi(buffer_int16, buf_size / sizeof(int16_t)); + buf_pos = 0; + } } } } @@ -162,16 +178,18 @@ void* mt32emu_init(wchar_t *control_rom, wchar_t *pcm_rom) event = thread_create_event(); thread_h = thread_create(mt32_thread, 0); samplerate = mt32emu_get_actual_stereo_output_samplerate(context); - buf_size = samplerate/RENDER_RATE*2; + /* buf_size = samplerate/RENDER_RATE*2; */ if (sound_is_float) { - buffer = malloc(buf_size * sizeof(float)); + buf_size = (samplerate/RENDER_RATE)*2*BUFFER_SEGMENTS*sizeof(float); + buffer = malloc(buf_size); buffer_int16 = NULL; } else { + buf_size = (samplerate/RENDER_RATE)*2*BUFFER_SEGMENTS*sizeof(int16_t); buffer = NULL; - buffer_int16 = malloc(buf_size * sizeof(int16_t)); + buffer_int16 = malloc(buf_size); } mt32emu_set_output_gain(context, device_get_config_int("output_gain")/100.0f); diff --git a/src/mem.c b/src/mem.c index 5ab4e5899..0fe8a0dd7 100644 --- a/src/mem.c +++ b/src/mem.c @@ -40,7 +40,7 @@ static int _mem_state[0x40000]; static mem_mapping_t base_mapping; mem_mapping_t ram_low_mapping; mem_mapping_t ram_high_mapping; -static mem_mapping_t ram_mid_mapping; +mem_mapping_t ram_mid_mapping; static mem_mapping_t ram_remapped_mapping; mem_mapping_t bios_mapping[8]; mem_mapping_t bios_high_mapping[8]; diff --git a/src/mem.h b/src/mem.h index 651095b6b..ec9c44740 100644 --- a/src/mem.h +++ b/src/mem.h @@ -176,6 +176,7 @@ void mem_flush_write_page(uint32_t addr, uint32_t virt); void mem_reset_page_blocks(); extern mem_mapping_t ram_low_mapping; +extern mem_mapping_t ram_mid_mapping; void mem_remap_top_256k(); void mem_remap_top_384k(); diff --git a/src/scat.c b/src/scat.c index 77dd8f308..5758cd4b9 100644 --- a/src/scat.c +++ b/src/scat.c @@ -27,6 +27,7 @@ void scat_shadow_state_update() { int i, val; + /* TODO - ROMCS enable features should be implemented later. */ for (i = 0; i < 24; i++) { val = ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTERNAL; @@ -95,7 +96,7 @@ void scat_set_xms_bound(uint8_t val) break; } - if ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3) + if ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3) { if (val != 1) { @@ -133,8 +134,12 @@ uint32_t get_scat_addr(uint32_t addr, scat_t *p) } else if (p == NULL && mem_size < 2048 && ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) > 7)) addr &= 0x7FFFF; - if ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3 && addr >= 0x100000) - addr -= 0x60000; + + if ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3) + { + if(addr >= 0x100000) addr -= 0x60000; + else if(addr >= 0xA0000) addr = 0xFFFFFFFF; + } return addr; } @@ -153,8 +158,9 @@ void scat_set_global_EMS_state(int state) { virt_addr = get_scat_addr(base_addr, &scat_stat[i]); if(i < 24) mem_mapping_disable(&scat_4000_9FFF_mapping[i]); - mem_mapping_set_exec(&scat_mapping[i], ram + virt_addr); mem_mapping_enable(&scat_mapping[i]); + if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&scat_mapping[i], ram + virt_addr); + else mem_mapping_set_exec(&scat_mapping[i], NULL); } else { @@ -214,11 +220,18 @@ void scat_write(uint16_t port, uint8_t val, void *priv) { if((val & 0x0F) == 3) { + if(mem_size > 640) mem_mapping_disable(&scat_A000_BFFF_mapping); + if(mem_size > 768) mem_mapping_disable(&ram_mid_mapping); mem_mapping_enable(&scat_shadowram_mapping); } else { mem_mapping_disable(&scat_shadowram_mapping); + if(mem_size > 640 && (val & 0x0F) > 3) + { + mem_mapping_enable(&scat_A000_BFFF_mapping); + if(mem_size > 768) mem_mapping_enable(&ram_mid_mapping); + } } if(mem_size < 2048) { @@ -252,6 +265,9 @@ void scat_write(uint16_t port, uint8_t val, void *priv) } if (scat_reg_valid) scat_regs[scat_index] = val; +#ifndef RELEASE_BUILD + else pclog("Attemped to write unimplemented SCAT register %02X at %04X:%04X\n", scat_index, val, CS, cpu_state.pc); +#endif if (scat_shadow_update) scat_shadow_state_update(); break; @@ -271,19 +287,27 @@ void scat_write(uint16_t port, uint8_t val, void *priv) break; case 0x208: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) + case 0x218: + if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { index = scat_ems_reg_2xA & 0x1F; scat_stat[index].regs_2x8 = val; + base_addr = (index + 16) << 14; + if(index >= 24) + base_addr += 0x30000; if((scat_regs[SCAT_EMS_CONTROL] & 0x80) && (scat_stat[index].regs_2x9 & 0x80)) { + virt_addr = get_scat_addr(base_addr, &scat_stat[index]); + if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&scat_mapping[index], ram + virt_addr); + else mem_mapping_set_exec(&scat_mapping[index], NULL); flushmmucache(); } } break; case 0x209: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) + case 0x219: + if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { index = scat_ems_reg_2xA & 0x1F; scat_stat[index].regs_2x9 = val; @@ -297,7 +321,8 @@ void scat_write(uint16_t port, uint8_t val, void *priv) { virt_addr = get_scat_addr(base_addr, &scat_stat[index]); if(index < 24) mem_mapping_disable(&scat_4000_9FFF_mapping[index]); - mem_mapping_set_exec(&scat_mapping[index], ram + virt_addr); + if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&scat_mapping[index], ram + virt_addr); + else mem_mapping_set_exec(&scat_mapping[index], NULL); mem_mapping_enable(&scat_mapping[index]); } else @@ -316,61 +341,8 @@ void scat_write(uint16_t port, uint8_t val, void *priv) } break; case 0x20A: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) - { - scat_ems_reg_2xA = val; - } - break; - - case 0x218: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) - { - index = scat_ems_reg_2xA & 0x1F; - scat_stat[index].regs_2x8 = val; - - if((scat_regs[SCAT_EMS_CONTROL] & 0x80) && (scat_stat[index].regs_2x9 & 0x80)) - { - flushmmucache(); - } - } - break; - case 0x219: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) - { - index = scat_ems_reg_2xA & 0x1F; - scat_stat[index].regs_2x9 = val; - base_addr = (index + 16) << 14; - if (index >= 24) - base_addr += 0x30000; - - if (scat_regs[SCAT_EMS_CONTROL] & 0x80) - { - if (val & 0x80) - { - virt_addr = get_scat_addr(base_addr, &scat_stat[index]); - if(index < 24) mem_mapping_disable(&scat_4000_9FFF_mapping[index]); - mem_mapping_set_exec(&scat_mapping[index], ram + virt_addr); - mem_mapping_enable(&scat_mapping[index]); - pclog("Map page %d(address %05X) to address %06X\n", scat_ems_reg_2xA & 0x1f, base_addr, virt_addr); - } - else - { - mem_mapping_set_exec(&scat_mapping[index], ram + base_addr); - mem_mapping_disable(&scat_mapping[index]); - if(index < 24) mem_mapping_enable(&scat_4000_9FFF_mapping[index]); - pclog("Unmap page %d(address %05X)\n", scat_ems_reg_2xA & 0x1f, base_addr); - } - flushmmucache(); - } - - if (scat_ems_reg_2xA & 0x80) - { - scat_ems_reg_2xA = (scat_ems_reg_2xA & 0xe0) | ((scat_ems_reg_2xA + 1) & 0x1f); - } - } - break; case 0x21A: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) + if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { scat_ems_reg_2xA = val; } @@ -403,42 +375,24 @@ uint8_t scat_read(uint16_t port, void *priv) break; case 0x208: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) + case 0x218: + if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { index = scat_ems_reg_2xA & 0x1F; val = scat_stat[index].regs_2x8; } break; case 0x209: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) + case 0x219: + if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { index = scat_ems_reg_2xA & 0x1F; val = scat_stat[index].regs_2x9; } break; case 0x20A: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) - { - val = scat_ems_reg_2xA; - } - break; - - case 0x218: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) - { - index = scat_ems_reg_2xA & 0x1F; - val = scat_stat[index].regs_2x8; - } - break; - case 0x219: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) - { - index = scat_ems_reg_2xA & 0x1F; - val = scat_stat[index].regs_2x9; - } - break; case 0x21A: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) + if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { val = scat_ems_reg_2xA; }