Mercurial > repos > blastem
comparison vdp.c @ 2359:04d29635d238
Support for arrays in debugger language
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 28 Oct 2023 14:39:19 -0700 |
parents | 4b2ac43c106e |
children | 3350b3c8faa8 |
comparison
equal
deleted
inserted
replaced
2358:4b2ac43c106e | 2359:04d29635d238 |
---|---|
923 context->sprite_draw_list[context->sprite_draws].address = tile_address; | 923 context->sprite_draw_list[context->sprite_draws].address = tile_address; |
924 context->cur_slot--; | 924 context->cur_slot--; |
925 } | 925 } |
926 } | 926 } |
927 | 927 |
928 #define CRAM_BITS 0xEEE | |
929 #define VSRAM_BITS 0x7FF | |
930 #define VSRAM_DIRTY_BITS 0xF800 | 928 #define VSRAM_DIRTY_BITS 0xF800 |
931 | 929 |
932 //rough estimate of slot number at which border display starts | 930 //rough estimate of slot number at which border display starts |
933 #define BG_START_SLOT 6 | 931 #define BG_START_SLOT 6 |
934 | 932 |
4600 hv |= get_ext_vcounter(context); | 4598 hv |= get_ext_vcounter(context); |
4601 | 4599 |
4602 return hv; | 4600 return hv; |
4603 } | 4601 } |
4604 | 4602 |
4603 void vdp_reg_write(vdp_context *context, uint16_t reg, uint16_t value) | |
4604 { | |
4605 uint8_t mode_5 = context->regs[REG_MODE_2] & BIT_MODE_5; | |
4606 if (reg < (mode_5 ? VDP_REGS : 0xB)) { | |
4607 //printf("register %d set to %X\n", reg, value & 0xFF); | |
4608 if (reg == REG_MODE_1 && (value & BIT_HVC_LATCH) && !(context->regs[reg] & BIT_HVC_LATCH)) { | |
4609 vdp_latch_hv(context); | |
4610 } else if (reg == REG_BG_COLOR) { | |
4611 value &= 0x3F; | |
4612 } else if (reg == REG_MODE_2 && context->type != VDP_GENESIS) { | |
4613 // only the Genesis VDP does anything with this bit | |
4614 // so just clear it to prevent Mode 5 selection if we're not emulating that chip | |
4615 value &= ~BIT_MODE_5; | |
4616 } | |
4617 /*if (reg == REG_MODE_4 && ((value ^ context->regs[reg]) & BIT_H40)) { | |
4618 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); | |
4619 }*/ | |
4620 uint8_t buffer[2] = {reg, value}; | |
4621 event_log(EVENT_VDP_REG, context->cycles, sizeof(buffer), buffer); | |
4622 context->regs[reg] = value; | |
4623 if (reg == REG_MODE_4) { | |
4624 context->double_res = (value & (BIT_INTERLACE | BIT_DOUBLE_RES)) == (BIT_INTERLACE | BIT_DOUBLE_RES); | |
4625 if (!context->double_res) { | |
4626 context->flags2 &= ~FLAG2_EVEN_FIELD; | |
4627 } | |
4628 } | |
4629 if (reg == REG_MODE_1 || reg == REG_MODE_2 || reg == REG_MODE_4) { | |
4630 update_video_params(context); | |
4631 } | |
4632 } else if (reg == REG_KMOD_CTRL) { | |
4633 if (!(value & 0xFF)) { | |
4634 context->system->enter_debugger = 1; | |
4635 } | |
4636 } else if (reg == REG_KMOD_MSG) { | |
4637 char c = value; | |
4638 if (c) { | |
4639 context->kmod_buffer_length++; | |
4640 if ((context->kmod_buffer_length + 1) > context->kmod_buffer_storage) { | |
4641 context->kmod_buffer_storage = context->kmod_buffer_length ? 128 : context->kmod_buffer_length * 2; | |
4642 context->kmod_msg_buffer = realloc(context->kmod_msg_buffer, context->kmod_buffer_storage); | |
4643 } | |
4644 context->kmod_msg_buffer[context->kmod_buffer_length - 1] = c; | |
4645 } else if (context->kmod_buffer_length) { | |
4646 context->kmod_msg_buffer[context->kmod_buffer_length] = 0; | |
4647 if (is_stdout_enabled()) { | |
4648 init_terminal(); | |
4649 printf("KDEBUG MESSAGE: %s\n", context->kmod_msg_buffer); | |
4650 } else { | |
4651 // GDB remote debugging is enabled, use stderr instead | |
4652 fprintf(stderr, "KDEBUG MESSAGE: %s\n", context->kmod_msg_buffer); | |
4653 } | |
4654 context->kmod_buffer_length = 0; | |
4655 } | |
4656 } else if (reg == REG_KMOD_TIMER) { | |
4657 if (!(value & 0x80)) { | |
4658 if (is_stdout_enabled()) { | |
4659 init_terminal(); | |
4660 printf("KDEBUG TIMER: %d\n", (context->cycles - context->timer_start_cycle) / 7); | |
4661 } else { | |
4662 // GDB remote debugging is enabled, use stderr instead | |
4663 fprintf(stderr, "KDEBUG TIMER: %d\n", (context->cycles - context->timer_start_cycle) / 7); | |
4664 } | |
4665 } | |
4666 if (value & 0xC0) { | |
4667 context->timer_start_cycle = context->cycles; | |
4668 } | |
4669 } | |
4670 } | |
4671 | |
4605 int vdp_control_port_write(vdp_context * context, uint16_t value, uint32_t cpu_cycle) | 4672 int vdp_control_port_write(vdp_context * context, uint16_t value, uint32_t cpu_cycle) |
4606 { | 4673 { |
4607 //printf("control port write: %X at %d\n", value, context->cycles); | 4674 //printf("control port write: %X at %d\n", value, context->cycles); |
4608 if (context->flags & FLAG_DMA_RUN) { | 4675 if (context->flags & FLAG_DMA_RUN) { |
4609 return -1; | 4676 return -1; |
4653 uint8_t mode_5 = context->regs[REG_MODE_2] & BIT_MODE_5; | 4720 uint8_t mode_5 = context->regs[REG_MODE_2] & BIT_MODE_5; |
4654 context->address = context->address_latch | (value & 0x3FFF); | 4721 context->address = context->address_latch | (value & 0x3FFF); |
4655 context->cd = (context->cd & 0x3C) | (value >> 14); | 4722 context->cd = (context->cd & 0x3C) | (value >> 14); |
4656 if ((value & 0xC000) == 0x8000) { | 4723 if ((value & 0xC000) == 0x8000) { |
4657 //Register write | 4724 //Register write |
4658 uint8_t reg = (value >> 8) & 0x1F; | 4725 uint16_t reg = (value >> 8) & 0x1F; |
4659 if (reg < (mode_5 ? VDP_REGS : 0xB)) { | 4726 vdp_reg_write(context, reg, value); |
4660 //printf("register %d set to %X\n", reg, value & 0xFF); | |
4661 if (reg == REG_MODE_1 && (value & BIT_HVC_LATCH) && !(context->regs[reg] & BIT_HVC_LATCH)) { | |
4662 vdp_latch_hv(context); | |
4663 } else if (reg == REG_BG_COLOR) { | |
4664 value &= 0x3F; | |
4665 } else if (reg == REG_MODE_2 && context->type != VDP_GENESIS) { | |
4666 // only the Genesis VDP does anything with this bit | |
4667 // so just clear it to prevent Mode 5 selection if we're not emulating that chip | |
4668 value &= ~BIT_MODE_5; | |
4669 } | |
4670 /*if (reg == REG_MODE_4 && ((value ^ context->regs[reg]) & BIT_H40)) { | |
4671 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); | |
4672 }*/ | |
4673 uint8_t buffer[2] = {reg, value}; | |
4674 event_log(EVENT_VDP_REG, context->cycles, sizeof(buffer), buffer); | |
4675 context->regs[reg] = value; | |
4676 if (reg == REG_MODE_4) { | |
4677 context->double_res = (value & (BIT_INTERLACE | BIT_DOUBLE_RES)) == (BIT_INTERLACE | BIT_DOUBLE_RES); | |
4678 if (!context->double_res) { | |
4679 context->flags2 &= ~FLAG2_EVEN_FIELD; | |
4680 } | |
4681 } | |
4682 if (reg == REG_MODE_1 || reg == REG_MODE_2 || reg == REG_MODE_4) { | |
4683 update_video_params(context); | |
4684 } | |
4685 } else if (reg == REG_KMOD_CTRL) { | |
4686 if (!(value & 0xFF)) { | |
4687 context->system->enter_debugger = 1; | |
4688 } | |
4689 } else if (reg == REG_KMOD_MSG) { | |
4690 char c = value; | |
4691 if (c) { | |
4692 context->kmod_buffer_length++; | |
4693 if ((context->kmod_buffer_length + 1) > context->kmod_buffer_storage) { | |
4694 context->kmod_buffer_storage = context->kmod_buffer_length ? 128 : context->kmod_buffer_length * 2; | |
4695 context->kmod_msg_buffer = realloc(context->kmod_msg_buffer, context->kmod_buffer_storage); | |
4696 } | |
4697 context->kmod_msg_buffer[context->kmod_buffer_length - 1] = c; | |
4698 } else if (context->kmod_buffer_length) { | |
4699 context->kmod_msg_buffer[context->kmod_buffer_length] = 0; | |
4700 if (is_stdout_enabled()) { | |
4701 init_terminal(); | |
4702 printf("KDEBUG MESSAGE: %s\n", context->kmod_msg_buffer); | |
4703 } else { | |
4704 // GDB remote debugging is enabled, use stderr instead | |
4705 fprintf(stderr, "KDEBUG MESSAGE: %s\n", context->kmod_msg_buffer); | |
4706 } | |
4707 context->kmod_buffer_length = 0; | |
4708 } | |
4709 } else if (reg == REG_KMOD_TIMER) { | |
4710 if (!(value & 0x80)) { | |
4711 if (is_stdout_enabled()) { | |
4712 init_terminal(); | |
4713 printf("KDEBUG TIMER: %d\n", (context->cycles - context->timer_start_cycle) / 7); | |
4714 } else { | |
4715 // GDB remote debugging is enabled, use stderr instead | |
4716 fprintf(stderr, "KDEBUG TIMER: %d\n", (context->cycles - context->timer_start_cycle) / 7); | |
4717 } | |
4718 } | |
4719 if (value & 0xC0) { | |
4720 context->timer_start_cycle = context->cycles; | |
4721 } | |
4722 } | |
4723 } else if (mode_5) { | 4727 } else if (mode_5) { |
4724 context->flags |= FLAG_PENDING; | 4728 context->flags |= FLAG_PENDING; |
4725 //Should these be taken care of here or after the second write? | 4729 //Should these be taken care of here or after the second write? |
4726 //context->flags &= ~FLAG_READ_FETCHED; | 4730 //context->flags &= ~FLAG_READ_FETCHED; |
4727 //context->flags2 &= ~FLAG2_READ_PENDING; | 4731 //context->flags2 &= ~FLAG2_READ_PENDING; |