diff options
author | Michael Pavone <pavone@retrodev.com> | 2017-01-05 00:36:23 -0800 |
---|---|---|
committer | Michael Pavone <pavone@retrodev.com> | 2017-01-05 00:36:23 -0800 |
commit | 25908ea88742215abdc04c491736e0061e99498e (patch) | |
tree | e5f3a7781fb700c4924fc0d2b9e596c640a38a5e | |
parent | f04fcbb10860e4a8431e3ea70f46ade4280f7c9f (diff) |
Implemented Mode 4 H conter latching
-rw-r--r-- | sms.c | 11 | ||||
-rw-r--r-- | vdp.c | 52 | ||||
-rw-r--r-- | vdp.h | 1 |
3 files changed, 46 insertions, 18 deletions
@@ -12,8 +12,19 @@ static void *memory_io_write(uint32_t location, void *vcontext, uint8_t value) z80_context *z80 = vcontext; sms_context *sms = z80->system; if (location & 1) { + uint8_t fuzzy_ctrl_0 = sms->io.ports[0].control, fuzzy_ctrl_1 = sms->io.ports[1].control; sms->io.ports[0].control = (~value) << 5 & 0x60; + fuzzy_ctrl_0 |= sms->io.ports[0].control; sms->io.ports[1].control = (~value) << 3 & 0x60; + fuzzy_ctrl_1 |= sms->io.ports[1].control; + if ( + (fuzzy_ctrl_0 & 0x40 & (sms->io.ports[0].output ^ (value << 1)) & (value << 1)) + || (fuzzy_ctrl_0 & 0x40 & (sms->io.ports[1].output ^ (value >> 1)) & (value >> 1)) + ) { + //TH is an output and it went from 0 -> 1 + vdp_run_context(sms->vdp, z80->current_cycle); + vdp_latch_hv(sms->vdp); + } io_data_write(sms->io.ports, value << 1, z80->current_cycle); io_data_write(sms->io.ports + 1, value >> 1, z80->current_cycle); } else { @@ -2140,6 +2140,39 @@ void vdp_run_dma_done(vdp_context * context, uint32_t target_cycles) } } +static uint16_t get_ext_vcounter(vdp_context *context) +{ + uint16_t line= context->vcounter & 0xFF; + if (context->double_res) { + line <<= 1; + if (line & 0x100) { + line |= 1; + } + } + return line << 8; +} + +void vdp_latch_hv(vdp_context *context) +{ + context->hv_latch = context->hslot | get_ext_vcounter(context); +} + +uint16_t vdp_hv_counter_read(vdp_context * context) +{ + if ((context->regs[REG_MODE_2] & BIT_MODE_5) && (context->regs[REG_MODE_1] & BIT_HVC_LATCH)) { + return context->hv_latch; + } + uint16_t hv; + if (context->regs[REG_MODE_2] & BIT_MODE_5) { + hv = context->hslot; + } else { + hv = context->hv_latch & 0xFF; + } + hv |= get_ext_vcounter(context); + + return hv; +} + int vdp_control_port_write(vdp_context * context, uint16_t value) { //printf("control port write: %X at %d\n", value, context->cycles); @@ -2184,7 +2217,7 @@ int vdp_control_port_write(vdp_context * context, uint16_t value) if (reg < (mode_5 ? VDP_REGS : 0xB)) { //printf("register %d set to %X\n", reg, value & 0xFF); if (reg == REG_MODE_1 && (value & BIT_HVC_LATCH) && !(context->regs[reg] & BIT_HVC_LATCH)) { - context->hv_latch = vdp_hv_counter_read(context); + vdp_latch_hv(context); } if (reg == REG_BG_COLOR) { value &= 0x3F; @@ -2388,23 +2421,6 @@ uint8_t vdp_data_port_read_pbc(vdp_context * context) return context->prefetch; } -uint16_t vdp_hv_counter_read(vdp_context * context) -{ - if ((context->regs[REG_MODE_2] & BIT_MODE_5) && (context->regs[REG_MODE_1] & BIT_HVC_LATCH)) { - return context->hv_latch; - } - uint32_t line= context->vcounter & 0xFF; - uint32_t linecyc = context->hslot; - linecyc &= 0xFF; - if (context->double_res) { - line <<= 1; - if (line & 0x100) { - line |= 1; - } - } - return (line << 8) | linecyc; -} - uint16_t vdp_test_port_read(vdp_context * context) { //TODO: Find out what actually gets returned here @@ -213,6 +213,7 @@ void vdp_test_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); uint8_t vdp_data_port_read_pbc(vdp_context * context); +void vdp_latch_hv(vdp_context *context); uint16_t vdp_hv_counter_read(vdp_context * context); uint16_t vdp_test_port_read(vdp_context * context); void vdp_adjust_cycles(vdp_context * context, uint32_t deduction); |