summaryrefslogtreecommitdiff
path: root/blastem.c
diff options
context:
space:
mode:
Diffstat (limited to 'blastem.c')
-rw-r--r--blastem.c114
1 files changed, 103 insertions, 11 deletions
diff --git a/blastem.c b/blastem.c
index de2d5a5..ddbf8ae 100644
--- a/blastem.c
+++ b/blastem.c
@@ -4,7 +4,7 @@
BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text.
*/
#include "68kinst.h"
-#include "m68k_to_x86.h"
+#include "m68k_core.h"
#include "z80_to_x86.h"
#include "mem.h"
#include "vdp.h"
@@ -182,6 +182,7 @@ uint8_t new_busack = 0;
void sync_z80(z80_context * z_context, uint32_t mclks)
{
+#ifndef NO_Z80
if (z80_enabled && !reset && !busreq) {
genesis_context * gen = z_context->system;
z_context->sync_cycle = mclks / MCLKS_PER_Z80;
@@ -198,14 +199,18 @@ void sync_z80(z80_context * z_context, uint32_t mclks)
}
if (z_context->iff1) {
z_context->int_cycle = z_context->int_pulse_start < z_context->int_enable_cycle ? z_context->int_enable_cycle : z_context->int_pulse_start;
+ } else {
+ z_context->int_cycle = CYCLE_NEVER;
}
z_context->target_cycle = z_context->sync_cycle < z_context->int_cycle ? z_context->sync_cycle : z_context->int_cycle;
dprintf("Running Z80 from cycle %d to cycle %d. Int cycle: %d\n", z_context->current_cycle, z_context->sync_cycle, z_context->int_cycle);
- z80_run(z_context);
+ z_context->run(z_context);
dprintf("Z80 ran to cycle %d\n", z_context->current_cycle);
}
}
- } else {
+ } else
+#endif
+ {
z_context->current_cycle = mclks / MCLKS_PER_Z80;
}
}
@@ -410,8 +415,9 @@ m68k_context * vdp_port_write_b(uint32_t vdp_port, m68k_context * context, uint8
return vdp_port_write(vdp_port, context, vdp_port < 0x10 ? value | value << 8 : ((vdp_port & 1) ? value : 0));
}
-z80_context * z80_vdp_port_write(uint16_t vdp_port, z80_context * context, uint8_t value)
+void * z80_vdp_port_write(uint32_t vdp_port, void * vcontext, uint8_t value)
{
+ z80_context * context = vcontext;
genesis_context * gen = context->system;
if (vdp_port & 0xE0) {
printf("machine freeze due to write to Z80 address %X\n", 0x7F00 | vdp_port);
@@ -480,6 +486,34 @@ uint8_t vdp_port_read_b(uint32_t vdp_port, m68k_context * context)
}
}
+uint8_t z80_vdp_port_read(uint32_t vdp_port, void * vcontext)
+{
+ z80_context * context = vcontext;
+ if (vdp_port & 0xE0) {
+ printf("machine freeze due to read from Z80 address %X\n", 0x7F00 | vdp_port);
+ exit(1);
+ }
+ genesis_context * gen = context->system;
+ vdp_port &= 0x1F;
+ uint16_t ret;
+ if (vdp_port < 0x10) {
+ //These probably won't currently interact well with the 68K accessing the VDP
+ vdp_run_context(gen->vdp, context->current_cycle * MCLKS_PER_Z80);
+ if (vdp_port < 4) {
+ ret = vdp_data_port_read(gen->vdp);
+ } else if (vdp_port < 8) {
+ ret = vdp_control_port_read(gen->vdp);
+ } else {
+ printf("Illegal write to HV Counter port %X\n", vdp_port);
+ exit(1);
+ }
+ } else {
+ //TODO: Figure out the correct value today
+ ret = 0xFFFF;
+ }
+ return vdp_port & 1 ? ret : ret >> 8;
+}
+
uint32_t zram_counter = 0;
#define Z80_ACK_DELAY 3
#define Z80_BUSY_DELAY 1//TODO: Find the actual value for this
@@ -499,7 +533,9 @@ m68k_context * io_write(uint32_t location, m68k_context * context, uint8_t value
location &= 0x7FFF;
if (location < 0x4000) {
z80_ram[location & 0x1FFF] = value;
+#ifndef NO_Z80
z80_handle_code_write(location & 0x1FFF, gen->z80);
+#endif
} else if (location < 0x6000) {
sync_sound(gen, context->current_cycle * MCLKS_PER_68K);
if (location & 1) {
@@ -699,8 +735,9 @@ uint16_t io_read_w(uint32_t location, m68k_context * context)
return value;
}
-z80_context * z80_write_ym(uint16_t location, z80_context * context, uint8_t value)
+void * z80_write_ym(uint32_t location, void * vcontext, uint8_t value)
{
+ z80_context * context = vcontext;
genesis_context * gen = context->system;
sync_sound(gen, context->current_cycle * MCLKS_PER_Z80);
if (location & 1) {
@@ -713,13 +750,55 @@ z80_context * z80_write_ym(uint16_t location, z80_context * context, uint8_t val
return context;
}
-uint8_t z80_read_ym(uint16_t location, z80_context * context)
+uint8_t z80_read_ym(uint32_t location, void * vcontext)
{
+ z80_context * context = vcontext;
genesis_context * gen = context->system;
sync_sound(gen, context->current_cycle * MCLKS_PER_Z80);
return ym_read_status(gen->ym);
}
+uint8_t z80_read_bank(uint32_t location, void * vcontext)
+{
+ z80_context * context = vcontext;
+ uint32_t address = context->bank_reg << 15 | location;
+ if (address >= 0xC00000 && address < 0xE00000) {
+ return z80_vdp_port_read(location & 0xFF, context);
+ } else {
+ fprintf(stderr, "Unhandled read by Z80 from address %X through banked memory area\n", address);
+ }
+ return 0;
+}
+
+void *z80_write_bank(uint32_t location, void * vcontext, uint8_t value)
+{
+ z80_context * context = vcontext;
+ uint32_t address = context->bank_reg << 15 | location;
+ if (address >= 0xE00000) {
+ address &= 0xFFFF;
+ ((uint8_t *)ram)[address ^ 1] = value;
+ } else if (address >= 0xC00000) {
+ z80_vdp_port_write(location & 0xFF, context, value);
+ } else {
+ fprintf(stderr, "Unhandled write by Z80 to address %X through banked memory area\n", address);
+ }
+ return context;
+}
+
+void *z80_write_bank_reg(uint32_t location, void * vcontext, uint8_t value)
+{
+ z80_context * context = vcontext;
+
+ context->bank_reg = (context->bank_reg >> 1 | value << 8) & 0x1FF;
+ if (context->bank_reg < 0x80) {
+ context->mem_pointers[1] = context->mem_pointers[2] + (context->bank_reg << 15);
+ } else {
+ context->mem_pointers[1] = NULL;
+ }
+
+ return context;
+}
+
uint16_t read_sram_w(uint32_t address, m68k_context * context)
{
genesis_context * gen = context->system;
@@ -894,7 +973,7 @@ void save_sram()
void init_run_cpu(genesis_context * gen, FILE * address_log, char * statefile, uint8_t * debugger)
{
m68k_context context;
- x86_68k_options opts;
+ m68k_options opts;
gen->m68k = &context;
memmap_chunk memmap[MAX_MAP_CHUNKS];
uint32_t num_chunks;
@@ -988,9 +1067,9 @@ void init_run_cpu(genesis_context * gen, FILE * address_log, char * statefile, u
}
atexit(save_sram);
}
- init_x86_68k_opts(&opts, memmap, num_chunks);
+ init_m68k_opts(&opts, memmap, num_chunks);
opts.address_log = address_log;
- init_68k_context(&context, opts.native_code_map, &opts);
+ init_68k_context(&context, opts.gen.native_code_map, &opts);
context.video_context = gen->vdp;
context.system = gen;
@@ -1016,7 +1095,9 @@ void init_run_cpu(genesis_context * gen, FILE * address_log, char * statefile, u
insert_breakpoint(&context, pc, debugger);
}
adjust_int_cycle(gen->m68k, gen->vdp);
+#ifndef NO_Z80
gen->z80->native_pc = z80_get_native_address_trans(gen->z80, gen->z80->pc);
+#endif
start_68k_context(&context, pc);
} else {
if (debugger) {
@@ -1095,6 +1176,15 @@ void detect_region()
}
}
}
+#ifndef NO_Z80
+const memmap_chunk z80_map[] = {
+ { 0x0000, 0x4000, 0x1FFF, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, z80_ram, NULL, NULL, NULL, NULL },
+ { 0x8000, 0x10000, 0x7FFF, 1, MMAP_READ | MMAP_PTR_IDX | MMAP_FUNC_NULL | MMAP_BYTESWAP, NULL, NULL, NULL, z80_read_bank, z80_write_bank},
+ { 0x4000, 0x6000, 0x0003, 0, 0, NULL, NULL, NULL, z80_read_ym, z80_write_ym},
+ { 0x6000, 0x6100, 0xFFFF, 0, 0, NULL, NULL, NULL, NULL, z80_write_bank_reg},
+ { 0x7F00, 0x8000, 0x00FF, 0, 0, NULL, NULL, NULL, z80_vdp_port_read, z80_vdp_port_write}
+};
+#endif
int main(int argc, char ** argv)
{
@@ -1260,9 +1350,11 @@ int main(int argc, char ** argv)
psg_init(&p_context, render_sample_rate(), gen.master_clock, MCLKS_PER_PSG, render_audio_buffer());
z80_context z_context;
- x86_z80_options z_opts;
- init_x86_z80_opts(&z_opts);
+#ifndef NO_Z80
+ z80_options z_opts;
+ init_x86_z80_opts(&z_opts, z80_map, 5);
init_z80_context(&z_context, &z_opts);
+#endif
z_context.system = &gen;
z_context.mem_pointers[0] = z80_ram;