comparison vdp.c @ 1946:c3c62dbf1ceb

WIP netplay support
author Michael Pavone <pavone@retrodev.com>
date Wed, 29 Apr 2020 01:00:57 -0700
parents c7e3e3ebb64a
children 275f1c4bdb25
comparison
equal deleted inserted replaced
1945:ba7231d2411c 1946:c3c62dbf1ceb
7 #include "blastem.h" 7 #include "blastem.h"
8 #include <stdlib.h> 8 #include <stdlib.h>
9 #include <string.h> 9 #include <string.h>
10 #include "render.h" 10 #include "render.h"
11 #include "util.h" 11 #include "util.h"
12 #include "event_log.h"
12 13
13 #define NTSC_INACTIVE_START 224 14 #define NTSC_INACTIVE_START 224
14 #define PAL_INACTIVE_START 240 15 #define PAL_INACTIVE_START 240
15 #define MODE4_INACTIVE_START 192 16 #define MODE4_INACTIVE_START 192
16 #define BUF_BIT_PRIORITY 0x40 17 #define BUF_BIT_PRIORITY 0x40
906 if (context->fifo_read >= 0 && start->cycle <= context->cycles) { 907 if (context->fifo_read >= 0 && start->cycle <= context->cycles) {
907 switch (start->cd & 0xF) 908 switch (start->cd & 0xF)
908 { 909 {
909 case VRAM_WRITE: 910 case VRAM_WRITE:
910 if ((context->regs[REG_MODE_2] & (BIT_128K_VRAM|BIT_MODE_5)) == (BIT_128K_VRAM|BIT_MODE_5)) { 911 if ((context->regs[REG_MODE_2] & (BIT_128K_VRAM|BIT_MODE_5)) == (BIT_128K_VRAM|BIT_MODE_5)) {
912 event_vram_word(context->cycles, start->address, start->value);
911 vdp_check_update_sat(context, start->address, start->value); 913 vdp_check_update_sat(context, start->address, start->value);
912 write_vram_word(context, start->address, start->value); 914 write_vram_word(context, start->address, start->value);
913 } else { 915 } else {
914 uint8_t byte = start->partial == 1 ? start->value >> 8 : start->value; 916 uint8_t byte = start->partial == 1 ? start->value >> 8 : start->value;
915 vdp_check_update_sat_byte(context, start->address ^ 1, byte); 917 uint32_t address = start->address ^ 1;
916 write_vram_byte(context, start->address ^ 1, byte); 918 event_vram_byte(context->cycles, start->address, byte, context->regs[REG_AUTOINC]);
919 vdp_check_update_sat_byte(context, address, byte);
920 write_vram_byte(context, address, byte);
917 if (!start->partial) { 921 if (!start->partial) {
918 start->address = start->address ^ 1; 922 start->address = address;
919 start->partial = 1; 923 start->partial = 1;
920 //skip auto-increment and removal of entry from fifo 924 //skip auto-increment and removal of entry from fifo
921 return; 925 return;
922 } 926 }
923 } 927 }
924 break; 928 break;
925 case CRAM_WRITE: { 929 case CRAM_WRITE: {
926 //printf("CRAM Write | %X to %X\n", start->value, (start->address/2) & (CRAM_SIZE-1)); 930 //printf("CRAM Write | %X to %X\n", start->value, (start->address/2) & (CRAM_SIZE-1));
931 uint16_t val;
927 if (start->partial == 3) { 932 if (start->partial == 3) {
928 uint16_t val;
929 if ((start->address & 1) && (context->regs[REG_MODE_2] & BIT_MODE_5)) { 933 if ((start->address & 1) && (context->regs[REG_MODE_2] & BIT_MODE_5)) {
930 val = (context->cram[start->address >> 1 & (CRAM_SIZE-1)] & 0xFF) | start->value << 8; 934 val = (context->cram[start->address >> 1 & (CRAM_SIZE-1)] & 0xFF) | start->value << 8;
931 } else { 935 } else {
932 uint16_t address = (context->regs[REG_MODE_2] & BIT_MODE_5) ? start->address >> 1 & (CRAM_SIZE-1) : start->address & 0x1F; 936 uint16_t address = (context->regs[REG_MODE_2] & BIT_MODE_5) ? start->address >> 1 & (CRAM_SIZE-1) : start->address & 0x1F;
933 val = (context->cram[address] & 0xFF00) | start->value; 937 val = (context->cram[address] & 0xFF00) | start->value;
934 } 938 }
935 write_cram(context, start->address, val);
936 } else { 939 } else {
937 write_cram(context, start->address, start->partial ? context->fifo[context->fifo_write].value : start->value); 940 val = start->partial ? context->fifo[context->fifo_write].value : start->value;
938 } 941 }
942 uint8_t buffer[3] = {start->address, val >> 8, val};
943 event_log(EVENT_CRAM, context->cycles, sizeof(buffer), buffer);
944 write_cram(context, start->address, val);
939 break; 945 break;
940 } 946 }
941 case VSRAM_WRITE: 947 case VSRAM_WRITE:
942 if (((start->address/2) & 63) < context->vsram_size) { 948 if (((start->address/2) & 63) < context->vsram_size) {
943 //printf("VSRAM Write: %X to %X @ frame: %d, vcounter: %d, hslot: %d, cycle: %d\n", start->value, start->address, context->frame, context->vcounter, context->hslot, context->cycles); 949 //printf("VSRAM Write: %X to %X @ frame: %d, vcounter: %d, hslot: %d, cycle: %d\n", start->value, start->address, context->frame, context->vcounter, context->hslot, context->cycles);
950 context->vsram[(start->address/2) & 63] |= start->value; 956 context->vsram[(start->address/2) & 63] |= start->value;
951 } 957 }
952 } else { 958 } else {
953 context->vsram[(start->address/2) & 63] = start->partial ? context->fifo[context->fifo_write].value : start->value; 959 context->vsram[(start->address/2) & 63] = start->partial ? context->fifo[context->fifo_write].value : start->value;
954 } 960 }
961 uint8_t buffer[3] = {(start->address/2) & 63, context->vsram[(start->address/2) & 63] >> 8, context->vsram[(start->address/2) & 63]};
962 event_log(EVENT_VSRAM, context->cycles, sizeof(buffer), buffer);
955 } 963 }
956 964
957 break; 965 break;
958 } 966 }
959 context->fifo_read = (context->fifo_read+1) & (FIFO_SIZE-1); 967 context->fifo_read = (context->fifo_read+1) & (FIFO_SIZE-1);
2108 } 2116 }
2109 context->cur_buffer = is_even ? FRAMEBUFFER_EVEN : FRAMEBUFFER_ODD; 2117 context->cur_buffer = is_even ? FRAMEBUFFER_EVEN : FRAMEBUFFER_ODD;
2110 context->pushed_frame = 1; 2118 context->pushed_frame = 1;
2111 context->fb = NULL; 2119 context->fb = NULL;
2112 } 2120 }
2121 //TODO: Check whether this happens before or after the cycle increment
2122 event_flush(context->cycles);
2113 vdp_update_per_frame_debug(context); 2123 vdp_update_per_frame_debug(context);
2114 context->h40_lines = 0; 2124 context->h40_lines = 0;
2115 context->frame++; 2125 context->frame++;
2116 context->output_lines = 0; 2126 context->output_lines = 0;
2117 } 2127 }
3758 value &= 0x3F; 3768 value &= 0x3F;
3759 } 3769 }
3760 /*if (reg == REG_MODE_4 && ((value ^ context->regs[reg]) & BIT_H40)) { 3770 /*if (reg == REG_MODE_4 && ((value ^ context->regs[reg]) & BIT_H40)) {
3761 printf("Mode changed from H%d to H%d @ %d, frame: %d\n", context->regs[reg] & BIT_H40 ? 40 : 32, value & BIT_H40 ? 40 : 32, context->cycles, context->frame); 3771 printf("Mode changed from H%d to H%d @ %d, frame: %d\n", context->regs[reg] & BIT_H40 ? 40 : 32, value & BIT_H40 ? 40 : 32, context->cycles, context->frame);
3762 }*/ 3772 }*/
3773 uint8_t buffer[2] = {reg, value};
3774 event_log(EVENT_VDP_REG, context->cycles, sizeof(buffer), buffer);
3763 context->regs[reg] = value; 3775 context->regs[reg] = value;
3764 if (reg == REG_MODE_4) { 3776 if (reg == REG_MODE_4) {
3765 context->double_res = (value & (BIT_INTERLACE | BIT_DOUBLE_RES)) == (BIT_INTERLACE | BIT_DOUBLE_RES); 3777 context->double_res = (value & (BIT_INTERLACE | BIT_DOUBLE_RES)) == (BIT_INTERLACE | BIT_DOUBLE_RES);
3766 if (!context->double_res) { 3778 if (!context->double_res) {
3767 context->flags2 &= ~FLAG2_EVEN_FIELD; 3779 context->flags2 &= ~FLAG2_EVEN_FIELD;
4549 context->debug_modes[i]++; 4561 context->debug_modes[i]++;
4550 return; 4562 return;
4551 } 4563 }
4552 } 4564 }
4553 } 4565 }
4566
4567 void vdp_replay_event(vdp_context *context, uint8_t event, event_reader *reader)
4568 {
4569 uint32_t address;
4570 deserialize_buffer *buffer = &reader->buffer;
4571 switch (event)
4572 {
4573 case EVENT_VRAM_BYTE:
4574 address = load_int16(buffer);
4575 break;
4576 case EVENT_VRAM_BYTE_DELTA:
4577 address = reader->last_byte_address + load_int8(buffer);
4578 break;
4579 case EVENT_VRAM_BYTE_ONE:
4580 address = reader->last_byte_address + 1;
4581 break;
4582 case EVENT_VRAM_BYTE_AUTO:
4583 address = reader->last_byte_address + context->regs[REG_AUTOINC];
4584 break;
4585 case EVENT_VRAM_WORD:
4586 address = load_int8(buffer) << 16;
4587 address |= load_int16(buffer);
4588 break;
4589 case EVENT_VRAM_WORD_DELTA:
4590 address = reader->last_word_address + load_int8(buffer);
4591 break;
4592 case EVENT_VDP_REG:
4593 case EVENT_CRAM:
4594 case EVENT_VSRAM:
4595 address = load_int8(buffer);
4596 break;
4597 }
4598
4599 switch (event)
4600 {
4601 case EVENT_VDP_REG: {
4602 uint8_t value = load_int8(buffer);
4603 context->regs[address] = value;
4604 if (address == REG_MODE_4) {
4605 context->double_res = (value & (BIT_INTERLACE | BIT_DOUBLE_RES)) == (BIT_INTERLACE | BIT_DOUBLE_RES);
4606 if (!context->double_res) {
4607 context->flags2 &= ~FLAG2_EVEN_FIELD;
4608 }
4609 }
4610 if (address == REG_MODE_1 || address == REG_MODE_2 || address == REG_MODE_4) {
4611 update_video_params(context);
4612 }
4613 break;
4614 }
4615 case EVENT_VRAM_BYTE:
4616 case EVENT_VRAM_BYTE_DELTA:
4617 case EVENT_VRAM_BYTE_ONE:
4618 case EVENT_VRAM_BYTE_AUTO: {
4619 uint8_t byte = load_int8(buffer);
4620 reader->last_byte_address = address;
4621 vdp_check_update_sat_byte(context, address ^ 1, byte);
4622 write_vram_byte(context, address ^ 1, byte);
4623 break;
4624 }
4625 case EVENT_VRAM_WORD:
4626 case EVENT_VRAM_WORD_DELTA: {
4627 uint16_t value = load_int16(buffer);
4628 reader->last_word_address = address;
4629 vdp_check_update_sat(context, address, value);
4630 write_vram_word(context, address, value);
4631 break;
4632 }
4633 case EVENT_CRAM:
4634 write_cram(context, address, load_int16(buffer));
4635 break;
4636 case EVENT_VSRAM:
4637 context->vsram[address] = load_int16(buffer);
4638 break;
4639 }
4640 }