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