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;