summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Pavone <pavone@retrodev.com>2017-01-05 00:36:23 -0800
committerMichael Pavone <pavone@retrodev.com>2017-01-05 00:36:23 -0800
commit25908ea88742215abdc04c491736e0061e99498e (patch)
treee5f3a7781fb700c4924fc0d2b9e596c640a38a5e
parentf04fcbb10860e4a8431e3ea70f46ade4280f7c9f (diff)
Implemented Mode 4 H conter latching
-rw-r--r--sms.c11
-rw-r--r--vdp.c52
-rw-r--r--vdp.h1
3 files changed, 46 insertions, 18 deletions
diff --git a/sms.c b/sms.c
index 170f2ce..b74b6dd 100644
--- a/sms.c
+++ b/sms.c
@@ -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 {
diff --git a/vdp.c b/vdp.c
index ae0f7ba..af04a05 100644
--- a/vdp.c
+++ b/vdp.c
@@ -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
diff --git a/vdp.h b/vdp.h
index 59944b5..76fee6e 100644
--- a/vdp.h
+++ b/vdp.h
@@ -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);