comparison vdp.c @ 2260:3f155bc13183

Less broken TMS9918A text mode
author Michael Pavone <pavone@retrodev.com>
date Sun, 18 Dec 2022 23:32:33 -0800
parents 425b44fd7bf1
children a98b2d0de2f1
comparison
equal deleted inserted replaced
2259:425b44fd7bf1 2260:3f155bc13183
127 context->border_bot = calc_crop(bot_crop, BORDER_BOT_V24_PAL); 127 context->border_bot = calc_crop(bot_crop, BORDER_BOT_V24_PAL);
128 } else { 128 } else {
129 border_top = BORDER_TOP_V24; 129 border_top = BORDER_TOP_V24;
130 context->border_bot = calc_crop(bot_crop, BORDER_BOT_V24); 130 context->border_bot = calc_crop(bot_crop, BORDER_BOT_V24);
131 } 131 }
132 if (!(context->regs[REG_MODE_1] & BIT_MODE_4)){ 132 if (!(context->regs[REG_MODE_1] & BIT_MODE_4) && context->type == VDP_GENESIS){
133 context->state = INACTIVE; 133 context->state = INACTIVE;
134 } else if (context->state == INACTIVE) { 134 } else if (context->state == INACTIVE) {
135 //Undo forced INACTIVE state due to neither Mode 4 nor Mode 5 being active 135 //Undo forced INACTIVE state due to neither Mode 4 nor Mode 5 being active
136 if (context->vcounter < context->inactive_start) { 136 if (context->vcounter < context->inactive_start) {
137 context->state = ACTIVE; 137 context->state = ACTIVE;
3578 3578
3579 3579
3580 static void tms_fetch_pattern_name(vdp_context *context) 3580 static void tms_fetch_pattern_name(vdp_context *context)
3581 { 3581 {
3582 uint16_t address = context->regs[REG_SCROLL_A] << 10 & 0x3C00; 3582 uint16_t address = context->regs[REG_SCROLL_A] << 10 & 0x3C00;
3583 address |= context->vcounter << 2 & 0x03E0; 3583 if (context->regs[REG_MODE_2] & BIT_M1) {
3584 address += context->hslot >> 2; 3584 //Text mode
3585 address |= (context->vcounter >> 3) * 40;
3586 address += (context->hslot - 4) / 3;
3587 } else {
3588 //Graphics/Multicolor
3589 address |= context->vcounter << 2 & 0x03E0;
3590 address |= context->hslot >> 2;
3591 }
3585 //TODO: 4K/16K mode address remapping when emulating TMS9918A 3592 //TODO: 4K/16K mode address remapping when emulating TMS9918A
3586 address = mode4_address_map[address] ^ 1; 3593 address = mode4_address_map[address] ^ 1;
3587 context->col_1 = context->vdpmem[address]; 3594 context->col_1 = context->vdpmem[address];
3588 } 3595 }
3589 3596
3786 if (context->hslot < (256 + BORDER_LEFT - (BORDER_LEFT-8))/2 || context->hslot > 256-32) { 3793 if (context->hslot < (256 + BORDER_LEFT - (BORDER_LEFT-8))/2 || context->hslot > 256-32) {
3787 tms_sprite_clock(context, 0); 3794 tms_sprite_clock(context, 0);
3788 tms_sprite_clock(context, 1); 3795 tms_sprite_clock(context, 1);
3789 } 3796 }
3790 if (!context->output) { 3797 if (!context->output) {
3791 return; 3798 if ((context->hslot * 2 - 6 + BORDER_LEFT) == (256 + BORDER_LEFT + BORDER_RIGHT)) {
3799 advance_output_line(context);
3800 }
3801 if (!context->output) {
3802 return;
3803 }
3792 } 3804 }
3793 uint32_t color; 3805 uint32_t color;
3794 if (context->type == VDP_GAMEGEAR) { 3806 if (context->type == VDP_GAMEGEAR) {
3795 //Game Gear uses CRAM entries 16-31 for TMS9918A modes 3807 //Game Gear uses CRAM entries 16-31 for TMS9918A modes
3796 color = context->colors[(context->regs[REG_BG_COLOR] & 0xF) + 16 + MODE4_OFFSET]; 3808 color = context->colors[(context->regs[REG_BG_COLOR] & 0xF) + 16 + MODE4_OFFSET];
3880 color = (color & 0xE) | (color << 1 & 0x20); 3892 color = (color & 0xE) | (color << 1 & 0x20);
3881 context->output[context->hslot * 2 - 7 + BORDER_LEFT] = context->color_map[color | FBUF_TMS]; 3893 context->output[context->hslot * 2 - 7 + BORDER_LEFT] = context->color_map[color | FBUF_TMS];
3882 } 3894 }
3883 } 3895 }
3884 3896
3885 #define TMS_OUTPUT(slot) if ((slot) < 8 || (slot) > (256 + BORDER_LEFT - 8) / 2) { tms_border(context); } else { tms_composite(context); } 3897 #define TMS_OUTPUT(slot) if ((slot) < 4 || (slot) > (256 + BORDER_LEFT - 8) / 2) { tms_border(context); } else { tms_composite(context); }
3886 #define TMS_OUTPUT_RIGHT(slot) \ 3898 #define TMS_OUTPUT_RIGHT(slot) \
3887 if ((slot) < (256 + BORDER_LEFT - (BORDER_LEFT - 8))/2) {\ 3899 if ((slot) < (256 + BORDER_LEFT - (BORDER_LEFT - 8))/2) {\
3888 tms_composite(context);\ 3900 tms_composite(context);\
3889 } else if ((slot < (256 + BORDER_LEFT + BORDER_RIGHT -(BORDER_LEFT - 8))/2)) {\ 3901 } else if ((slot < (256 + BORDER_LEFT + BORDER_RIGHT -(BORDER_LEFT - 8))/2)) {\
3890 tms_border(context);\ 3902 tms_border(context);\
4080 context->hslot++; 4092 context->hslot++;
4081 context->cycles += MCLKS_SLOT_H32; 4093 context->cycles += MCLKS_SLOT_H32;
4082 } 4094 }
4083 } 4095 }
4084 4096
4085 #define TMS_CHECK_LIMIT_SKIP context->hslot+=2; context->cycles += MCLKS_SLOT_H32; if (context->cycles >= target_cycles) { return; } 4097 #define TMS_TEXT_OUTPUT(slot) if ((slot) < 8) { tms_border(context); } else { tms_composite(context); }
4086 #define TMS_TEXT_BLOCK(slot) \ 4098 #define TMS_TEXT_BLOCK(slot) \
4087 case slot:\ 4099 case slot:\
4100 TMS_TEXT_OUTPUT(slot)\
4088 tms_fetch_pattern_name(context);\ 4101 tms_fetch_pattern_name(context);\
4089 TMS_CHECK_LIMIT \ 4102 TMS_CHECK_LIMIT \
4090 case slot+1:\ 4103 case slot+1:\
4104 TMS_TEXT_OUTPUT(slot+1)\
4091 external_slot(context);\ 4105 external_slot(context);\
4092 TMS_CHECK_LIMIT_SKIP \ 4106 TMS_CHECK_LIMIT \
4093 case slot+3:\ 4107 case slot+2:\
4108 TMS_TEXT_OUTPUT(slot+2)\
4094 tms_fetch_pattern_value(context);\ 4109 tms_fetch_pattern_value(context);\
4095 TMS_CHECK_LIMIT 4110 TMS_CHECK_LIMIT
4096 4111
4097 static void vdp_tms_text(vdp_context * context, uint32_t target_cycles) 4112 static void vdp_tms_text(vdp_context * context, uint32_t target_cycles)
4098 { 4113 {
4099 switch (context->hslot) 4114 switch (context->hslot)
4100 { 4115 {
4101 for (;;) 4116 for (;;)
4102 { 4117 {
4103 TMS_TEXT_BLOCK(0) 4118 case 0:
4119 tms_border(context);
4120 external_slot(context);
4121 TMS_CHECK_LIMIT
4122 case 1:
4123 tms_border(context);
4124 external_slot(context);
4125 TMS_CHECK_LIMIT
4126 case 2:
4127 tms_border(context);
4128 external_slot(context);
4129 TMS_CHECK_LIMIT
4130 case 3:
4131 tms_border(context);
4132 external_slot(context);
4133 TMS_CHECK_LIMIT
4104 TMS_TEXT_BLOCK(4) 4134 TMS_TEXT_BLOCK(4)
4105 TMS_TEXT_BLOCK(8) 4135 TMS_TEXT_BLOCK(7)
4106 TMS_TEXT_BLOCK(12) 4136 TMS_TEXT_BLOCK(10)
4137 TMS_TEXT_BLOCK(13)
4107 TMS_TEXT_BLOCK(16) 4138 TMS_TEXT_BLOCK(16)
4108 TMS_TEXT_BLOCK(20) 4139 TMS_TEXT_BLOCK(19)
4109 TMS_TEXT_BLOCK(24) 4140 TMS_TEXT_BLOCK(22)
4141 TMS_TEXT_BLOCK(25)
4110 TMS_TEXT_BLOCK(28) 4142 TMS_TEXT_BLOCK(28)
4111 TMS_TEXT_BLOCK(32) 4143 TMS_TEXT_BLOCK(31)
4112 TMS_TEXT_BLOCK(36) 4144 TMS_TEXT_BLOCK(34)
4145 TMS_TEXT_BLOCK(37)
4113 TMS_TEXT_BLOCK(40) 4146 TMS_TEXT_BLOCK(40)
4114 TMS_TEXT_BLOCK(44) 4147 TMS_TEXT_BLOCK(43)
4115 TMS_TEXT_BLOCK(48) 4148 TMS_TEXT_BLOCK(46)
4149 TMS_TEXT_BLOCK(49)
4116 TMS_TEXT_BLOCK(52) 4150 TMS_TEXT_BLOCK(52)
4117 TMS_TEXT_BLOCK(56) 4151 TMS_TEXT_BLOCK(55)
4118 TMS_TEXT_BLOCK(60) 4152 TMS_TEXT_BLOCK(58)
4153 TMS_TEXT_BLOCK(61)
4119 TMS_TEXT_BLOCK(64) 4154 TMS_TEXT_BLOCK(64)
4120 TMS_TEXT_BLOCK(68) 4155 TMS_TEXT_BLOCK(67)
4121 TMS_TEXT_BLOCK(72) 4156 TMS_TEXT_BLOCK(70)
4157 TMS_TEXT_BLOCK(73)
4122 TMS_TEXT_BLOCK(76) 4158 TMS_TEXT_BLOCK(76)
4123 TMS_TEXT_BLOCK(80) 4159 TMS_TEXT_BLOCK(79)
4124 TMS_TEXT_BLOCK(84) 4160 TMS_TEXT_BLOCK(82)
4161 TMS_TEXT_BLOCK(85)
4125 TMS_TEXT_BLOCK(88) 4162 TMS_TEXT_BLOCK(88)
4126 TMS_TEXT_BLOCK(92) 4163 TMS_TEXT_BLOCK(91)
4127 TMS_TEXT_BLOCK(96) 4164 TMS_TEXT_BLOCK(94)
4165 TMS_TEXT_BLOCK(97)
4128 TMS_TEXT_BLOCK(100) 4166 TMS_TEXT_BLOCK(100)
4129 TMS_TEXT_BLOCK(104) 4167 TMS_TEXT_BLOCK(103)
4130 TMS_TEXT_BLOCK(108) 4168 TMS_TEXT_BLOCK(106)
4169 TMS_TEXT_BLOCK(109)
4131 TMS_TEXT_BLOCK(112) 4170 TMS_TEXT_BLOCK(112)
4132 TMS_TEXT_BLOCK(116) 4171 TMS_TEXT_BLOCK(115)
4133 TMS_TEXT_BLOCK(120) 4172 TMS_TEXT_BLOCK(118)
4134 TMS_TEXT_BLOCK(124) 4173 TMS_TEXT_BLOCK(121)
4135 TMS_TEXT_BLOCK(128) 4174 case 124:
4136 TMS_TEXT_BLOCK(132) 4175 tms_composite(context);
4137 TMS_TEXT_BLOCK(136) 4176 external_slot(context);
4138 TMS_TEXT_BLOCK(140) 4177 TMS_CHECK_LIMIT
4139 TMS_TEXT_BLOCK(144) 4178 case 125:
4140 TMS_TEXT_BLOCK(148) 4179 tms_composite(context);
4141 TMS_TEXT_BLOCK(152) 4180 external_slot(context);
4142 TMS_TEXT_BLOCK(156) 4181 TMS_CHECK_LIMIT
4182 case 126:
4183 tms_composite(context);
4184 external_slot(context);
4185 TMS_CHECK_LIMIT
4143 default: 4186 default:
4144 while (context->hslot < 179) 4187 while (context->hslot < 139)
4188 {
4189 tms_border(context);
4190 external_slot(context);
4191 TMS_CHECK_LIMIT
4192 }
4193 while (context->hslot < 147)
4145 { 4194 {
4146 external_slot(context); 4195 external_slot(context);
4147 TMS_CHECK_LIMIT 4196 TMS_CHECK_LIMIT
4148 } 4197 }
4149 if (context->hslot == 179) { 4198 if (context->hslot == 147) {
4150 external_slot(context); 4199 external_slot(context);
4151 context->hslot = 233; 4200 context->hslot = 233;
4152 context->cycles += MCLKS_SLOT_H32; 4201 context->cycles += MCLKS_SLOT_H32;
4153 if (context->cycles >= target_cycles) { return; } 4202 if (context->cycles >= target_cycles) { return; }
4154 } 4203 }
4155 while (context->hslot > 179) { 4204 while (context->hslot > 147) {
4156 if (context->hslot >= 233) { 4205 if (context->hslot >= 233) {
4157 external_slot(context); 4206 external_slot(context);
4158 if (context->hslot + 1 == LINE_CHANGE_MODE4) { 4207 if (context->hslot + 1 == LINE_CHANGE_MODE4) {
4159 vdp_advance_line(context); 4208 vdp_advance_line(context);
4160 } 4209 }