# HG changeset patch # User Mike Pavone # Date 1357052817 28800 # Node ID 139e5dcd6aa3a17a9e3250f5f6f228d4793d4e9f # Parent 4a400aec81bb47d09e8531bd41a2ea1e42819278 Make writes to control and data port block when DMA is in progress diff -r 4a400aec81bb -r 139e5dcd6aa3 blastem.c --- a/blastem.c Tue Jan 01 07:04:48 2013 -0800 +++ b/blastem.c Tue Jan 01 07:06:57 2013 -0800 @@ -115,11 +115,9 @@ sync_components(context); vdp_context * v_context = context->next_context; if (vdp_port < 0x10) { + int blocked; if (vdp_port < 4) { - vdp_data_port_write(v_context, value); - } else if(vdp_port < 8) { - int blocked = vdp_control_port_write(v_context, value); - if (blocked) { + while (vdp_data_port_write(v_context, value) < 0) { while(v_context->flags & FLAG_DMA_RUN) { vdp_run_dma_done(v_context, MCLKS_PER_FRAME); if (v_context->cycles >= MCLKS_PER_FRAME) { @@ -130,6 +128,27 @@ } } context->current_cycle = v_context->cycles / MCLKS_PER_68K; + } + } else if(vdp_port < 8) { + blocked = vdp_control_port_write(v_context, value); + if (blocked) { + while (blocked) { + while(v_context->flags & FLAG_DMA_RUN) { + vdp_run_dma_done(v_context, MCLKS_PER_FRAME); + if (v_context->cycles >= MCLKS_PER_FRAME) { + wait_render_frame(v_context); + vdp_adjust_cycles(v_context, MCLKS_PER_FRAME); + io_adjust_cycles(&gamepad_1, v_context->cycles/MCLKS_PER_68K, MCLKS_PER_FRAME/MCLKS_PER_68K); + io_adjust_cycles(&gamepad_2, v_context->cycles/MCLKS_PER_68K, MCLKS_PER_FRAME/MCLKS_PER_68K); + } + } + if (blocked < 0) { + blocked = vdp_control_port_write(v_context, value); + } else { + blocked = 0; + } + } + context->current_cycle = v_context->cycles / MCLKS_PER_68K; } else { if (v_context->regs[REG_MODE_2] & 0x20 && ((context->status & 0x7) < 6)) { if (context->int_cycle > VINT_CYCLE) { diff -r 4a400aec81bb -r 139e5dcd6aa3 runtime.S --- a/runtime.S Tue Jan 01 07:04:48 2013 -0800 +++ b/runtime.S Tue Jan 01 07:06:57 2013 -0800 @@ -209,6 +209,9 @@ push %rbx /* fetch VDP context pointer from 68K context */ mov 128(%rsi), %rdx + /* check DMA flag */ + bt $6, 19(%rdx) + jc fifo_fallback /* get fifo_cur and compare it to fifo_end */ mov (%rdx), %rbx cmp %rbx, 8(%rdx) diff -r 4a400aec81bb -r 139e5dcd6aa3 vdp.c --- a/vdp.c Tue Jan 01 07:04:48 2013 -0800 +++ b/vdp.c Tue Jan 01 07:06:57 2013 -0800 @@ -184,7 +184,7 @@ //TODO: Figure out what happens if CD bit 4 is not set in DMA copy mode //TODO: Figure out what happens when CD:0-3 is not set to a write mode in DMA operations //TODO: Figure out what happens if DMA gets disabled part way through a DMA fill or DMA copy - if((context->regs[REG_MODE_2] & BIT_DMA_ENABLE) && (context->flags & FLAG_DMA_RUN)) { + if(context->flags & FLAG_DMA_RUN) { uint16_t dma_len; switch(context->regs[REG_DMASRC_H] & 0xC0) { @@ -1022,6 +1022,9 @@ int vdp_control_port_write(vdp_context * context, uint16_t value) { //printf("control port write: %X\n", value); + if (context->flags & FLAG_DMA_RUN) { + return -1; + } if (context->flags & FLAG_PENDING) { context->address = (context->address & 0x3FFF) | (value << 14); context->cd = (context->cd & 0x3) | ((value >> 2) & 0x3C); @@ -1057,9 +1060,16 @@ return 0; } -void vdp_data_port_write(vdp_context * context, uint16_t value) +int vdp_data_port_write(vdp_context * context, uint16_t value) { //printf("data port write: %X\n", value); + if (context->flags & FLAG_DMA_RUN) { + return -1; + } + if (!(context->cd & 1)) { + //ignore writes when cd is configured for read + return 0; + } context->flags &= ~FLAG_PENDING; /*if (context->fifo_cur == context->fifo_end) { printf("FIFO full, waiting for space before next write at cycle %X\n", context->cycles); @@ -1074,6 +1084,7 @@ context->fifo_cur->partial = 0; context->fifo_cur++; context->address += context->regs[REG_AUTOINC]; + return 0; } uint16_t vdp_control_port_read(vdp_context * context) @@ -1086,7 +1097,7 @@ if (context->fifo_cur == context->fifo_end) { value |= 0x100; } - if ((context->regs[REG_MODE_2] & BIT_DMA_ENABLE) && (context->flags & FLAG_DMA_RUN)) { + if (context->flags & FLAG_DMA_RUN) { value |= 0x2; } uint32_t line= context->cycles / MCLKS_LINE; diff -r 4a400aec81bb -r 139e5dcd6aa3 vdp.h --- a/vdp.h Tue Jan 01 07:04:48 2013 -0800 +++ b/vdp.h Tue Jan 01 07:06:57 2013 -0800 @@ -126,7 +126,7 @@ void vdp_load_savestate(vdp_context * context, FILE * state_file); void vdp_save_state(vdp_context * context, FILE * outfile); int vdp_control_port_write(vdp_context * context, uint16_t value); -void vdp_data_port_write(vdp_context * context, uint16_t value); +int vdp_data_port_write(vdp_context * context, uint16_t value); uint16_t vdp_control_port_read(vdp_context * context); uint16_t vdp_data_port_read(vdp_context * context); uint16_t vdp_hv_counter_read(vdp_context * context);