Mercurial > repos > blastem
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 } |