summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vdp.c47
-rw-r--r--vdp.h2
2 files changed, 36 insertions, 13 deletions
diff --git a/vdp.c b/vdp.c
index 37ad611..d3798f1 100644
--- a/vdp.c
+++ b/vdp.c
@@ -976,7 +976,7 @@ static void external_slot(vdp_context * context)
context->flags |= FLAG_READ_FETCHED;
}
- } else if (!(context->cd & 1) && !(context->flags & (FLAG_READ_FETCHED|FLAG_PENDING))) {
+ } else if (!(context->cd & 1) && !(context->flags & FLAG_READ_FETCHED)) {
switch(context->cd & 0xF)
{
case VRAM_READ:
@@ -2752,7 +2752,7 @@ static void vdp_h40(vdp_context * context, uint32_t target_cycles)
{
case 165:
//only consider doing a line at a time if the FIFO is empty, there are no pending reads and there is no DMA running
- if (context->fifo_read == -1 && !(context->flags & FLAG_DMA_RUN) && ((context->cd & 1) || (context->flags & (FLAG_READ_FETCHED|FLAG_PENDING)))) {
+ if (context->fifo_read == -1 && !(context->flags & FLAG_DMA_RUN) && ((context->cd & 1) || (context->flags & FLAG_READ_FETCHED))) {
while (target_cycles - context->cycles >= MCLKS_LINE && context->state != PREPARING && context->vcounter != context->inactive_start) {
vdp_h40_line(context);
}
@@ -3691,6 +3691,13 @@ uint16_t vdp_hv_counter_read(vdp_context * context)
return hv;
}
+static void clear_pending(vdp_context *context)
+{
+ context->flags &= ~FLAG_PENDING;
+ context->address = context->address_latch;
+ context->cd = context->cd_latch;
+}
+
int vdp_control_port_write(vdp_context * context, uint16_t value)
{
//printf("control port write: %X at %d\n", value, context->cycles);
@@ -3698,12 +3705,12 @@ int vdp_control_port_write(vdp_context * context, uint16_t value)
return -1;
}
if (context->flags & FLAG_PENDING) {
- context->address = (context->address & 0x3FFF) | (value << 14 & 0x1C000);
+ context->address_latch = (context->address_latch & 0x3FFF) | (value << 14 & 0x1C000);
//It seems like the DMA enable bit doesn't so much enable DMA so much
//as it enables changing CD5 from control port writes
uint8_t preserve = (context->regs[REG_MODE_2] & BIT_DMA_ENABLE) ? 0x3 : 0x23;
- context->cd = (context->cd & preserve) | ((value >> 2) & ~preserve & 0xFF);
- context->flags &= ~FLAG_PENDING;
+ context->cd_latch = (context->cd_latch & preserve) | ((value >> 2) & ~preserve & 0xFF);
+ clear_pending(context);
//Should these be taken care of here or after the first write?
context->flags &= ~FLAG_READ_FETCHED;
context->flags2 &= ~FLAG2_READ_PENDING;
@@ -3734,8 +3741,8 @@ int vdp_control_port_write(vdp_context * context, uint16_t value)
uint8_t mode_5 = context->regs[REG_MODE_2] & BIT_MODE_5;
//contrary to what's in Charles MacDonald's doc, it seems top 2 address bits are cleared
//needed for the Mona in 344 Bytes demo
- context->address = value & 0x3FFF;
- context->cd = (context->cd & 0x3C) | (value >> 14);
+ context->address_latch = (context->address_latch & 0x1C000) | (value & 0x3FFF);
+ context->cd_latch = (context->cd_latch & 0x3C) | (value >> 14);
if ((value & 0xC000) == 0x8000) {
//Register write
uint8_t reg = (value >> 8) & 0x1F;
@@ -3797,7 +3804,7 @@ int vdp_data_port_write(vdp_context * context, uint16_t value)
return -1;
}
if (context->flags & FLAG_PENDING) {
- context->flags &= ~FLAG_PENDING;
+ clear_pending(context);
//Should these be cleared here?
context->flags &= ~FLAG_READ_FETCHED;
context->flags2 &= ~FLAG2_READ_PENDING;
@@ -3832,7 +3839,7 @@ int vdp_data_port_write(vdp_context * context, uint16_t value)
void vdp_data_port_write_pbc(vdp_context * context, uint8_t value)
{
if (context->flags & FLAG_PENDING) {
- context->flags &= ~FLAG_PENDING;
+ clear_pending(context);
//Should these be cleared here?
context->flags &= ~FLAG_READ_FETCHED;
context->flags2 &= ~FLAG2_READ_PENDING;
@@ -3871,7 +3878,9 @@ void vdp_test_port_write(vdp_context * context, uint16_t value)
uint16_t vdp_control_port_read(vdp_context * context)
{
- context->flags &= ~FLAG_PENDING;
+ if (context->flags & FLAG_PENDING) {
+ clear_pending(context);
+ }
context->flags2 &= ~FLAG2_BYTE_PENDING;
//Bits 15-10 are not fixed like Charles MacDonald's doc suggests, but instead open bus values that reflect 68K prefetch
uint16_t value = context->system->get_open_bus_value(context->system) & 0xFC00;
@@ -3921,7 +3930,7 @@ uint16_t vdp_control_port_read(vdp_context * context)
uint16_t vdp_data_port_read(vdp_context * context)
{
if (context->flags & FLAG_PENDING) {
- context->flags &= ~FLAG_PENDING;
+ clear_pending(context);
//Should these be cleared here?
context->flags &= ~FLAG_READ_FETCHED;
context->flags2 &= ~FLAG2_READ_PENDING;
@@ -3938,7 +3947,10 @@ uint16_t vdp_data_port_read(vdp_context * context)
uint8_t vdp_data_port_read_pbc(vdp_context * context)
{
- context->flags &= ~(FLAG_PENDING | FLAG_READ_FETCHED);
+ if (context->flags & FLAG_PENDING) {
+ clear_pending(context);
+ }
+ context->flags &= ~FLAG_READ_FETCHED;
context->flags2 &= ~FLAG2_BYTE_PENDING;
context->cd = VRAM_READ8;
@@ -4237,7 +4249,7 @@ void vdp_int_ack(vdp_context * context)
}
}
-#define VDP_STATE_VERSION 2
+#define VDP_STATE_VERSION 3
void vdp_serialize(vdp_context *context, serialize_buffer *buf)
{
save_int8(buf, VDP_STATE_VERSION);
@@ -4317,6 +4329,8 @@ void vdp_serialize(vdp_context *context, serialize_buffer *buf)
save_int32(buf, context->cycles);
save_int32(buf, context->pending_vint_start);
save_int32(buf, context->pending_hint_start);
+ save_int32(buf, context->address_latch);
+ save_int8(buf, context->cd_latch);
}
void vdp_deserialize(deserialize_buffer *buf, void *vcontext)
@@ -4451,6 +4465,13 @@ void vdp_deserialize(deserialize_buffer *buf, void *vcontext)
context->cycles = load_int32(buf);
context->pending_vint_start = load_int32(buf);
context->pending_hint_start = load_int32(buf);
+ if (version > 2) {
+ context->address_latch = load_int32(buf);
+ context->cd_latch = load_int8(buf);
+ } else {
+ context->address_latch = context->address;
+ context->cd_latch = context->cd;
+ }
update_video_params(context);
}
diff --git a/vdp.h b/vdp.h
index cd407d3..44dc46c 100644
--- a/vdp.h
+++ b/vdp.h
@@ -174,6 +174,7 @@ typedef struct {
int32_t fifo_write;
int32_t fifo_read;
uint32_t address;
+ uint32_t address_latch;
uint32_t serial_address;
uint32_t colors[CRAM_SIZE*4];
uint32_t debugcolors[1 << (3 + 1 + 1 + 1)];//3 bits for source, 1 bit for priority, 1 bit for shadow, 1 bit for hilight
@@ -181,6 +182,7 @@ typedef struct {
uint32_t frame;
uint32_t vsram_size;
uint8_t cd;
+ uint8_t cd_latch;
uint8_t flags;
uint8_t regs[VDP_REGS];
//cycle count in MCLKs