trunk/src/mame/video/mcd212.c
| r20519 | r20520 | |
| 24 | 24 | #include "video/mcd212.h" |
| 25 | 25 | #include "includes/cdi.h" |
| 26 | 26 | |
| 27 | // device type definition |
| 28 | const device_type MACHINE_MCD212 = &device_creator<mcd212_device>; |
| 29 | |
| 27 | 30 | #if ENABLE_VERBOSE_LOG |
| 28 | 31 | INLINE void verboselog(running_machine &machine, int n_level, const char *s_fmt, ...) |
| 29 | 32 | { |
| r20519 | r20520 | |
| 41 | 44 | #define verboselog(x,y,z,...) |
| 42 | 45 | #endif |
| 43 | 46 | |
| 44 | | static void cdi220_draw_lcd(running_machine &machine, int y); |
| 45 | | static void mcd212_update_region_arrays(mcd212_regs_t *mcd212); |
| 46 | | static void mcd212_set_display_parameters(mcd212_regs_t *mcd212, int channel, UINT8 value); |
| 47 | | static void mcd212_update_visible_area(running_machine &machine); |
| 48 | | static void mcd212_set_vsr(mcd212_regs_t *mcd212, int channel, UINT32 value); |
| 49 | | static void mcd212_set_dcp(mcd212_regs_t *mcd212, int channel, UINT32 value); |
| 50 | | static UINT32 mcd212_get_vsr(mcd212_regs_t *mcd212, int channel); |
| 51 | | static UINT32 mcd212_get_dcp(mcd212_regs_t *mcd212, int channel); |
| 52 | | static UINT32 mcd212_get_screen_width(mcd212_regs_t *mcd212); |
| 53 | | static void mcd212_set_register(running_machine &machine, int channel, UINT8 reg, UINT32 value); |
| 54 | | static void mcd212_process_ica(mcd212_regs_t *mcd212, int channel); |
| 55 | | static void mcd212_process_dca(mcd212_regs_t *mcd212, int channel); |
| 56 | | static void mcd212_process_vsr(mcd212_regs_t *mcd212, int channel, UINT8 *pixels_r, UINT8 *pixels_g, UINT8 *pixels_b); |
| 57 | | static void mcd212_mix_lines(mcd212_regs_t *mcd212, UINT8 *plane_a_r, UINT8 *plane_a_g, UINT8 *plane_a_b, UINT8 *plane_b_r, UINT8 *plane_b_g, UINT8 *plane_b_b, UINT32 *out); |
| 58 | | static void mcd212_draw_cursor(mcd212_regs_t *mcd212, UINT32 *scanline, int y); |
| 59 | | static void mcd212_draw_scanline(mcd212_regs_t *mcd212, int y); |
| 60 | | |
| 61 | 47 | static const UINT16 cdi220_lcd_char[20*22] = |
| 62 | 48 | { |
| 63 | 49 | 0x2000, 0x2000, 0x2000, 0x2000, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0200, 0x0200, 0x0200, 0x0200, |
| r20519 | r20520 | |
| 84 | 70 | 0x1000, 0x1000, 0x1000, 0x1000, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0400, 0x0400, 0x0400, 0x0400 |
| 85 | 71 | }; |
| 86 | 72 | |
| 87 | | static void cdi220_draw_lcd(running_machine &machine, int y) |
| 73 | void mcd212_device::draw_lcd(int y) |
| 88 | 74 | { |
| 89 | | cdi_state *state = machine.driver_data<cdi_state>(); |
| 75 | cdi_state *state = machine().driver_data<cdi_state>(); |
| 90 | 76 | bitmap_rgb32 &bitmap = state->m_lcdbitmap; |
| 91 | 77 | UINT32 *scanline = &bitmap.pix32(y); |
| 92 | 78 | int x = 0; |
| r20519 | r20520 | |
| 94 | 80 | |
| 95 | 81 | for(lcd = 0; lcd < 8; lcd++) |
| 96 | 82 | { |
| 97 | | cdislave_device *slave = downcast<cdislave_device *>(machine.device("slave")); |
| 98 | | UINT16 data = (slave->get_lcd_state()[lcd*2] << 8) | |
| 99 | | slave->get_lcd_state()[lcd*2 + 1]; |
| 83 | UINT16 data = (state->m_slave->get_lcd_state()[lcd*2] << 8) | |
| 84 | state->m_slave->get_lcd_state()[lcd*2 + 1]; |
| 100 | 85 | for(x = 0; x < 20; x++) |
| 101 | 86 | { |
| 102 | 87 | if(data & cdi220_lcd_char[y*20 + x]) |
| r20519 | r20520 | |
| 111 | 96 | } |
| 112 | 97 | } |
| 113 | 98 | |
| 114 | | static void mcd212_update_region_arrays(mcd212_regs_t *mcd212) |
| 99 | void mcd212_device::update_region_arrays() |
| 115 | 100 | { |
| 116 | | int x = 0; |
| 117 | 101 | int latched_rf0 = 0; |
| 118 | 102 | int latched_rf1 = 0; |
| 119 | | int latched_wfa = mcd212->channel[0].weight_factor_a[0]; |
| 120 | | int latched_wfb = mcd212->channel[1].weight_factor_b[0]; |
| 103 | int latched_wfa = m_channel[0].weight_factor_a[0]; |
| 104 | int latched_wfb = m_channel[1].weight_factor_b[0]; |
| 121 | 105 | int reg = 0; |
| 122 | 106 | |
| 123 | | for(x = 0; x < 768; x++) |
| 107 | for(int x = 0; x < 768; x++) |
| 124 | 108 | { |
| 125 | | if(mcd212->channel[0].image_coding_method & MCD212_ICM_NR) |
| 109 | if(m_channel[0].image_coding_method & MCD212_ICM_NR) |
| 126 | 110 | { |
| 127 | | int reg_ = 0; |
| 128 | | int flag = 0; |
| 129 | | |
| 130 | | for(flag = 0; flag < 2; flag++) |
| 111 | for(int flag = 0; flag < 2; flag++) |
| 131 | 112 | { |
| 132 | | for(reg_ = 0; reg_ < 4; reg_++) |
| 113 | for(int reg_ = 0; reg_ < 4; reg_++) |
| 133 | 114 | { |
| 134 | | if(mcd212->channel[0].region_control[reg_] == 0) |
| 115 | if(m_channel[0].region_control[reg_] == 0) |
| 135 | 116 | { |
| 136 | 117 | break; |
| 137 | 118 | } |
| 138 | | if(x == (mcd212->channel[0].region_control[flag*4 + reg_] & MCD212_RC_X)) |
| 119 | if(x == (m_channel[0].region_control[flag*4 + reg_] & MCD212_RC_X)) |
| 139 | 120 | { |
| 140 | | switch((mcd212->channel[0].region_control[flag*4 + reg_] & MCD212_RC_OP) >> MCD212_RC_OP_SHIFT) |
| 121 | switch((m_channel[0].region_control[flag*4 + reg_] & MCD212_RC_OP) >> MCD212_RC_OP_SHIFT) |
| 141 | 122 | { |
| 142 | 123 | case 0: // End of region control for line |
| 143 | 124 | break; |
| r20519 | r20520 | |
| 146 | 127 | case 3: // Not used |
| 147 | 128 | break; |
| 148 | 129 | case 4: // Change weight of plane A |
| 149 | | latched_wfa = (mcd212->channel[0].region_control[flag*4 + reg_] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 130 | latched_wfa = (m_channel[0].region_control[flag*4 + reg_] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 150 | 131 | break; |
| 151 | 132 | case 5: // Not used |
| 152 | 133 | break; |
| 153 | 134 | case 6: // Change weight of plane B |
| 154 | | latched_wfb = (mcd212->channel[0].region_control[flag*4 + reg_] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 135 | latched_wfb = (m_channel[0].region_control[flag*4 + reg_] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 155 | 136 | break; |
| 156 | 137 | case 7: // Not used |
| 157 | 138 | break; |
| r20519 | r20520 | |
| 179 | 160 | case 11: // Not used |
| 180 | 161 | break; |
| 181 | 162 | case 12: // Reset region flag and change weight of plane A |
| 182 | | latched_wfa = (mcd212->channel[0].region_control[flag*4 + reg_] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 163 | latched_wfa = (m_channel[0].region_control[flag*4 + reg_] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 183 | 164 | if(flag) |
| 184 | 165 | { |
| 185 | 166 | latched_rf1 = 0; |
| r20519 | r20520 | |
| 190 | 171 | } |
| 191 | 172 | break; |
| 192 | 173 | case 13: // Set region flag and change weight of plane A |
| 193 | | latched_wfa = (mcd212->channel[0].region_control[flag*4 + reg_] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 174 | latched_wfa = (m_channel[0].region_control[flag*4 + reg_] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 194 | 175 | if(flag) |
| 195 | 176 | { |
| 196 | 177 | latched_rf1 = 1; |
| r20519 | r20520 | |
| 201 | 182 | } |
| 202 | 183 | break; |
| 203 | 184 | case 14: // Reset region flag and change weight of plane B |
| 204 | | latched_wfb = (mcd212->channel[0].region_control[flag*4 + reg_] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 185 | latched_wfb = (m_channel[0].region_control[flag*4 + reg_] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 205 | 186 | if(flag) |
| 206 | 187 | { |
| 207 | 188 | latched_rf1 = 0; |
| r20519 | r20520 | |
| 212 | 193 | } |
| 213 | 194 | break; |
| 214 | 195 | case 15: // Set region flag and change weight of plane B |
| 215 | | latched_wfb = (mcd212->channel[0].region_control[flag*4 + reg_] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 196 | latched_wfb = (m_channel[0].region_control[flag*4 + reg_] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 216 | 197 | if(flag) |
| 217 | 198 | { |
| 218 | 199 | latched_rf1 = 1; |
| r20519 | r20520 | |
| 231 | 212 | { |
| 232 | 213 | if(reg < 8) |
| 233 | 214 | { |
| 234 | | int flag = (mcd212->channel[0].region_control[reg] & MCD212_RC_RF) >> MCD212_RC_RF_SHIFT; |
| 235 | | if(!(mcd212->channel[0].region_control[reg] & MCD212_RC_OP)) |
| 215 | int flag = (m_channel[0].region_control[reg] & MCD212_RC_RF) >> MCD212_RC_RF_SHIFT; |
| 216 | if(!(m_channel[0].region_control[reg] & MCD212_RC_OP)) |
| 236 | 217 | { |
| 237 | 218 | for(; x < 768; x++) |
| 238 | 219 | { |
| 239 | | mcd212->channel[0].weight_factor_a[x] = latched_wfa; |
| 240 | | mcd212->channel[1].weight_factor_b[x] = latched_wfb; |
| 241 | | mcd212->region_flag_0[x] = latched_rf0; |
| 242 | | mcd212->region_flag_1[x] = latched_rf1; |
| 220 | m_channel[0].weight_factor_a[x] = latched_wfa; |
| 221 | m_channel[1].weight_factor_b[x] = latched_wfb; |
| 222 | m_region_flag_0[x] = latched_rf0; |
| 223 | m_region_flag_1[x] = latched_rf1; |
| 243 | 224 | } |
| 244 | 225 | break; |
| 245 | 226 | } |
| 246 | | if(x == (mcd212->channel[0].region_control[reg] & MCD212_RC_X)) |
| 227 | if(x == (m_channel[0].region_control[reg] & MCD212_RC_X)) |
| 247 | 228 | { |
| 248 | | switch((mcd212->channel[0].region_control[reg] & MCD212_RC_OP) >> MCD212_RC_OP_SHIFT) |
| 229 | switch((m_channel[0].region_control[reg] & MCD212_RC_OP) >> MCD212_RC_OP_SHIFT) |
| 249 | 230 | { |
| 250 | 231 | case 0: // End of region control for line |
| 251 | 232 | break; |
| r20519 | r20520 | |
| 254 | 235 | case 3: // Not used |
| 255 | 236 | break; |
| 256 | 237 | case 4: // Change weight of plane A |
| 257 | | latched_wfa = (mcd212->channel[0].region_control[reg] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 238 | latched_wfa = (m_channel[0].region_control[reg] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 258 | 239 | break; |
| 259 | 240 | case 5: // Not used |
| 260 | 241 | break; |
| 261 | 242 | case 6: // Change weight of plane B |
| 262 | | latched_wfb = (mcd212->channel[0].region_control[reg] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 243 | latched_wfb = (m_channel[0].region_control[reg] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 263 | 244 | break; |
| 264 | 245 | case 7: // Not used |
| 265 | 246 | break; |
| r20519 | r20520 | |
| 287 | 268 | case 11: // Not used |
| 288 | 269 | break; |
| 289 | 270 | case 12: // Reset region flag and change weight of plane A |
| 290 | | latched_wfa = (mcd212->channel[0].region_control[reg] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 271 | latched_wfa = (m_channel[0].region_control[reg] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 291 | 272 | if(flag) |
| 292 | 273 | { |
| 293 | 274 | latched_rf1 = 0; |
| r20519 | r20520 | |
| 298 | 279 | } |
| 299 | 280 | break; |
| 300 | 281 | case 13: // Set region flag and change weight of plane A |
| 301 | | latched_wfa = (mcd212->channel[0].region_control[reg] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 282 | latched_wfa = (m_channel[0].region_control[reg] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 302 | 283 | if(flag) |
| 303 | 284 | { |
| 304 | 285 | latched_rf1 = 1; |
| r20519 | r20520 | |
| 309 | 290 | } |
| 310 | 291 | break; |
| 311 | 292 | case 14: // Reset region flag and change weight of plane B |
| 312 | | latched_wfb = (mcd212->channel[0].region_control[reg] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 293 | latched_wfb = (m_channel[0].region_control[reg] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 313 | 294 | if(flag) |
| 314 | 295 | { |
| 315 | 296 | latched_rf1 = 0; |
| r20519 | r20520 | |
| 320 | 301 | } |
| 321 | 302 | break; |
| 322 | 303 | case 15: // Set region flag and change weight of plane B |
| 323 | | latched_wfb = (mcd212->channel[0].region_control[reg] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 304 | latched_wfb = (m_channel[0].region_control[reg] & MCD212_RC_WF) >> MCD212_RC_WF_SHIFT; |
| 324 | 305 | if(flag) |
| 325 | 306 | { |
| 326 | 307 | latched_rf1 = 1; |
| r20519 | r20520 | |
| 335 | 316 | } |
| 336 | 317 | } |
| 337 | 318 | } |
| 338 | | mcd212->channel[0].weight_factor_a[x] = latched_wfa; |
| 339 | | mcd212->channel[1].weight_factor_b[x] = latched_wfb; |
| 340 | | mcd212->region_flag_0[x] = latched_rf0; |
| 341 | | mcd212->region_flag_1[x] = latched_rf1; |
| 319 | m_channel[0].weight_factor_a[x] = latched_wfa; |
| 320 | m_channel[1].weight_factor_b[x] = latched_wfb; |
| 321 | m_region_flag_0[x] = latched_rf0; |
| 322 | m_region_flag_1[x] = latched_rf1; |
| 342 | 323 | } |
| 343 | 324 | } |
| 344 | 325 | |
| 345 | | static void mcd212_set_vsr(mcd212_regs_t *mcd212, int channel, UINT32 value) |
| 326 | void mcd212_device::set_vsr(int channel, UINT32 value) |
| 346 | 327 | { |
| 347 | | mcd212->channel[channel].vsr = value & 0x0000ffff; |
| 348 | | mcd212->channel[channel].dcr &= 0xffc0; |
| 349 | | mcd212->channel[channel].dcr |= (value >> 16) & 0x003f; |
| 328 | m_channel[channel].vsr = value & 0x0000ffff; |
| 329 | m_channel[channel].dcr &= 0xffc0; |
| 330 | m_channel[channel].dcr |= (value >> 16) & 0x003f; |
| 350 | 331 | } |
| 351 | 332 | |
| 352 | | static void mcd212_set_register(running_machine &machine, int channel, UINT8 reg, UINT32 value) |
| 333 | void mcd212_device::set_register(int channel, UINT8 reg, UINT32 value) |
| 353 | 334 | { |
| 354 | | cdi_state *state = machine.driver_data<cdi_state>(); |
| 355 | | mcd212_regs_t *mcd212 = &state->m_mcd212_regs; |
| 356 | | |
| 357 | 335 | switch(reg) |
| 358 | 336 | { |
| 359 | 337 | case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: // CLUT 0 - 63 |
| r20519 | r20520 | |
| 364 | 342 | case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: |
| 365 | 343 | case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: |
| 366 | 344 | case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: |
| 367 | | verboselog(machine, 11, " %04xxxxx: %d: CLUT[%d] = %08x\n", channel * 0x20, channel, mcd212->channel[channel].clut_bank * 0x40 + (reg - 0x80), value ); |
| 368 | | mcd212->channel[0].clut_r[mcd212->channel[channel].clut_bank * 0x40 + (reg - 0x80)] = (UINT8)(value >> 16) & 0xfc; |
| 369 | | mcd212->channel[0].clut_g[mcd212->channel[channel].clut_bank * 0x40 + (reg - 0x80)] = (UINT8)(value >> 8) & 0xfc; |
| 370 | | mcd212->channel[0].clut_b[mcd212->channel[channel].clut_bank * 0x40 + (reg - 0x80)] = (UINT8)(value >> 0) & 0xfc; |
| 345 | verboselog(machine, 11, " %04xxxxx: %d: CLUT[%d] = %08x\n", channel * 0x20, channel, m_channel[channel].clut_bank * 0x40 + (reg - 0x80), value ); |
| 346 | m_channel[0].clut_r[m_channel[channel].clut_bank * 0x40 + (reg - 0x80)] = (UINT8)(value >> 16) & 0xfc; |
| 347 | m_channel[0].clut_g[m_channel[channel].clut_bank * 0x40 + (reg - 0x80)] = (UINT8)(value >> 8) & 0xfc; |
| 348 | m_channel[0].clut_b[m_channel[channel].clut_bank * 0x40 + (reg - 0x80)] = (UINT8)(value >> 0) & 0xfc; |
| 371 | 349 | break; |
| 372 | 350 | case 0xc0: // Image Coding Method |
| 373 | 351 | if(channel == 0) |
| 374 | 352 | { |
| 375 | 353 | verboselog(machine, 6, " %04xxxxx: %d: Image Coding Method = %08x\n", channel * 0x20, channel, value ); |
| 376 | | mcd212->channel[channel].image_coding_method = value; |
| 354 | m_channel[channel].image_coding_method = value; |
| 377 | 355 | } |
| 378 | 356 | break; |
| 379 | 357 | case 0xc1: // Transparency Control |
| 380 | 358 | if(channel == 0) |
| 381 | 359 | { |
| 382 | 360 | verboselog(machine, 6, " %04xxxxx: %d: Transparency Control = %08x\n", channel * 0x20, channel, value ); |
| 383 | | mcd212->channel[channel].transparency_control = value; |
| 361 | m_channel[channel].transparency_control = value; |
| 384 | 362 | } |
| 385 | 363 | break; |
| 386 | 364 | case 0xc2: // Plane Order |
| 387 | 365 | if(channel == 0) |
| 388 | 366 | { |
| 389 | 367 | verboselog(machine, 6, " %04xxxxx: %d: Plane Order = %08x\n", channel * 0x20, channel, value & 7); |
| 390 | | mcd212->channel[channel].plane_order = value & 0x00000007; |
| 368 | m_channel[channel].plane_order = value & 0x00000007; |
| 391 | 369 | } |
| 392 | 370 | break; |
| 393 | 371 | case 0xc3: // CLUT Bank Register |
| 394 | 372 | verboselog(machine, 6, " %04xxxxx: %d: CLUT Bank Register = %08x\n", channel * 0x20, channel, value & 3); |
| 395 | | mcd212->channel[channel].clut_bank = channel ? (2 | (value & 0x00000001)) : (value & 0x00000003); |
| 373 | m_channel[channel].clut_bank = channel ? (2 | (value & 0x00000001)) : (value & 0x00000003); |
| 396 | 374 | break; |
| 397 | 375 | case 0xc4: // Transparent Color A |
| 398 | 376 | if(channel == 0) |
| 399 | 377 | { |
| 400 | 378 | verboselog(machine, 6, " %04xxxxx: %d: Transparent Color A = %08x\n", channel * 0x20, channel, value ); |
| 401 | | mcd212->channel[channel].transparent_color_a = value & 0xfcfcfc; |
| 379 | m_channel[channel].transparent_color_a = value & 0xfcfcfc; |
| 402 | 380 | } |
| 403 | 381 | break; |
| 404 | 382 | case 0xc6: // Transparent Color B |
| 405 | 383 | if(channel == 1) |
| 406 | 384 | { |
| 407 | 385 | verboselog(machine, 6, " %04xxxxx: %d: Transparent Color B = %08x\n", channel * 0x20, channel, value ); |
| 408 | | mcd212->channel[channel].transparent_color_b = value & 0xfcfcfc; |
| 386 | m_channel[channel].transparent_color_b = value & 0xfcfcfc; |
| 409 | 387 | } |
| 410 | 388 | break; |
| 411 | 389 | case 0xc7: // Mask Color A |
| 412 | 390 | if(channel == 0) |
| 413 | 391 | { |
| 414 | 392 | verboselog(machine, 6, " %04xxxxx: %d: Mask Color A = %08x\n", channel * 0x20, channel, value ); |
| 415 | | mcd212->channel[channel].mask_color_a = value & 0xfcfcfc; |
| 393 | m_channel[channel].mask_color_a = value & 0xfcfcfc; |
| 416 | 394 | } |
| 417 | 395 | break; |
| 418 | 396 | case 0xc9: // Mask Color B |
| 419 | 397 | if(channel == 1) |
| 420 | 398 | { |
| 421 | 399 | verboselog(machine, 6, " %04xxxxx: %d: Mask Color B = %08x\n", channel * 0x20, channel, value ); |
| 422 | | mcd212->channel[channel].mask_color_b = value & 0xfcfcfc; |
| 400 | m_channel[channel].mask_color_b = value & 0xfcfcfc; |
| 423 | 401 | } |
| 424 | 402 | break; |
| 425 | 403 | case 0xca: // Delta YUV Absolute Start Value A |
| 426 | 404 | if(channel == 0) |
| 427 | 405 | { |
| 428 | 406 | verboselog(machine, 6, " %04xxxxx: %d: Delta YUV Absolute Start Value A = %08x\n", channel * 0x20, channel, value ); |
| 429 | | mcd212->channel[channel].dyuv_abs_start_a = value; |
| 407 | m_channel[channel].dyuv_abs_start_a = value; |
| 430 | 408 | } |
| 431 | 409 | break; |
| 432 | 410 | case 0xcb: // Delta YUV Absolute Start Value B |
| 433 | 411 | if(channel == 1) |
| 434 | 412 | { |
| 435 | 413 | verboselog(machine, 6, " %04xxxxx: %d: Delta YUV Absolute Start Value B = %08x\n", channel * 0x20, channel, value ); |
| 436 | | mcd212->channel[channel].dyuv_abs_start_b = value; |
| 414 | m_channel[channel].dyuv_abs_start_b = value; |
| 437 | 415 | } |
| 438 | 416 | break; |
| 439 | 417 | case 0xcd: // Cursor Position |
| 440 | 418 | if(channel == 0) |
| 441 | 419 | { |
| 442 | 420 | verboselog(machine, 6, " %04xxxxx: %d: Cursor Position = %08x\n", channel * 0x20, channel, value ); |
| 443 | | mcd212->channel[channel].cursor_position = value; |
| 421 | m_channel[channel].cursor_position = value; |
| 444 | 422 | } |
| 445 | 423 | break; |
| 446 | 424 | case 0xce: // Cursor Control |
| 447 | 425 | if(channel == 0) |
| 448 | 426 | { |
| 449 | 427 | verboselog(machine, 11, " %04xxxxx: %d: Cursor Control = %08x\n", channel * 0x20, channel, value ); |
| 450 | | mcd212->channel[channel].cursor_control = value; |
| 428 | m_channel[channel].cursor_control = value; |
| 451 | 429 | } |
| 452 | 430 | break; |
| 453 | 431 | case 0xcf: // Cursor Pattern |
| 454 | 432 | if(channel == 0) |
| 455 | 433 | { |
| 456 | 434 | verboselog(machine, 11, " %04xxxxx: %d: Cursor Pattern[%d] = %04x\n", channel * 0x20, channel, (value >> 16) & 0x000f, value & 0x0000ffff); |
| 457 | | mcd212->channel[channel].cursor_pattern[(value >> 16) & 0x000f] = value & 0x0000ffff; |
| 435 | m_channel[channel].cursor_pattern[(value >> 16) & 0x000f] = value & 0x0000ffff; |
| 458 | 436 | } |
| 459 | 437 | break; |
| 460 | 438 | case 0xd0: // Region Control 0-7 |
| r20519 | r20520 | |
| 466 | 444 | case 0xd6: |
| 467 | 445 | case 0xd7: |
| 468 | 446 | verboselog(machine, 6, " %04xxxxx: %d: Region Control %d = %08x\n", channel * 0x20, channel, reg & 7, value ); |
| 469 | | mcd212->channel[0].region_control[reg & 7] = value; |
| 470 | | mcd212_update_region_arrays(mcd212); |
| 447 | m_channel[0].region_control[reg & 7] = value; |
| 448 | update_region_arrays(); |
| 471 | 449 | break; |
| 472 | 450 | case 0xd8: // Backdrop Color |
| 473 | 451 | if(channel == 0) |
| 474 | 452 | { |
| 475 | 453 | verboselog(machine, 6, " %04xxxxx: %d: Backdrop Color = %08x\n", channel * 0x20, channel, value ); |
| 476 | | mcd212->channel[channel].backdrop_color = value; |
| 454 | m_channel[channel].backdrop_color = value; |
| 477 | 455 | } |
| 478 | 456 | break; |
| 479 | 457 | case 0xd9: // Mosaic Pixel Hold Factor A |
| 480 | 458 | if(channel == 0) |
| 481 | 459 | { |
| 482 | 460 | verboselog(machine, 6, " %04xxxxx: %d: Mosaic Pixel Hold Factor A = %08x\n", channel * 0x20, channel, value ); |
| 483 | | mcd212->channel[channel].mosaic_hold_a = value; |
| 461 | m_channel[channel].mosaic_hold_a = value; |
| 484 | 462 | } |
| 485 | 463 | break; |
| 486 | 464 | case 0xda: // Mosaic Pixel Hold Factor B |
| 487 | 465 | if(channel == 1) |
| 488 | 466 | { |
| 489 | 467 | verboselog(machine, 6, " %04xxxxx: %d: Mosaic Pixel Hold Factor B = %08x\n", channel * 0x20, channel, value ); |
| 490 | | mcd212->channel[channel].mosaic_hold_b = value; |
| 468 | m_channel[channel].mosaic_hold_b = value; |
| 491 | 469 | } |
| 492 | 470 | break; |
| 493 | 471 | case 0xdb: // Weight Factor A |
| 494 | 472 | if(channel == 0) |
| 495 | 473 | { |
| 496 | 474 | verboselog(machine, 6, " %04xxxxx: %d: Weight Factor A = %08x\n", channel * 0x20, channel, value ); |
| 497 | | memset(mcd212->channel[channel].weight_factor_a, value & 0x000000ff, 768); |
| 498 | | mcd212_update_region_arrays(mcd212); |
| 475 | memset(m_channel[channel].weight_factor_a, value & 0x000000ff, 768); |
| 476 | update_region_arrays(); |
| 499 | 477 | } |
| 500 | 478 | break; |
| 501 | 479 | case 0xdc: // Weight Factor B |
| 502 | 480 | if(channel == 1) |
| 503 | 481 | { |
| 504 | 482 | verboselog(machine, 6, " %04xxxxx: %d: Weight Factor B = %08x\n", channel * 0x20, channel, value ); |
| 505 | | memset(mcd212->channel[channel].weight_factor_b, value & 0x000000ff, 768); |
| 506 | | mcd212_update_region_arrays(mcd212); |
| 483 | memset(m_channel[channel].weight_factor_b, value & 0x000000ff, 768); |
| 484 | update_region_arrays(); |
| 507 | 485 | } |
| 508 | 486 | break; |
| 509 | 487 | } |
| 510 | 488 | } |
| 511 | 489 | |
| 512 | | static UINT32 mcd212_get_vsr(mcd212_regs_t *mcd212, int channel) |
| 490 | UINT32 mcd212_device::get_vsr(int channel) |
| 513 | 491 | { |
| 514 | | return ((mcd212->channel[channel].dcr & 0x3f) << 16) | mcd212->channel[channel].vsr; |
| 492 | return ((m_channel[channel].dcr & 0x3f) << 16) | m_channel[channel].vsr; |
| 515 | 493 | } |
| 516 | 494 | |
| 517 | | static void mcd212_set_dcp(mcd212_regs_t *mcd212, int channel, UINT32 value) |
| 495 | void mcd212_device::set_dcp(int channel, UINT32 value) |
| 518 | 496 | { |
| 519 | | mcd212->channel[channel].dcp = value & 0x0000ffff; |
| 520 | | mcd212->channel[channel].ddr &= 0xffc0; |
| 521 | | mcd212->channel[channel].ddr |= (value >> 16) & 0x003f; |
| 497 | m_channel[channel].dcp = value & 0x0000ffff; |
| 498 | m_channel[channel].ddr &= 0xffc0; |
| 499 | m_channel[channel].ddr |= (value >> 16) & 0x003f; |
| 522 | 500 | } |
| 523 | 501 | |
| 524 | | static UINT32 mcd212_get_dcp(mcd212_regs_t *mcd212, int channel) |
| 502 | UINT32 mcd212_device::get_dcp(int channel) |
| 525 | 503 | { |
| 526 | | return ((mcd212->channel[channel].ddr & 0x3f) << 16) | mcd212->channel[channel].dcp; |
| 504 | return ((m_channel[channel].ddr & 0x3f) << 16) | m_channel[channel].dcp; |
| 527 | 505 | } |
| 528 | 506 | |
| 529 | | static void mcd212_set_display_parameters(mcd212_regs_t *mcd212, int channel, UINT8 value) |
| 507 | void mcd212_device::set_display_parameters(int channel, UINT8 value) |
| 530 | 508 | { |
| 531 | | mcd212->channel[channel].ddr &= 0xf0ff; |
| 532 | | mcd212->channel[channel].ddr |= (value & 0x0f) << 8; |
| 533 | | mcd212->channel[channel].dcr &= 0xf7ff; |
| 534 | | mcd212->channel[channel].dcr |= (value & 0x10) << 7; |
| 509 | m_channel[channel].ddr &= 0xf0ff; |
| 510 | m_channel[channel].ddr |= (value & 0x0f) << 8; |
| 511 | m_channel[channel].dcr &= 0xf7ff; |
| 512 | m_channel[channel].dcr |= (value & 0x10) << 7; |
| 535 | 513 | } |
| 536 | 514 | |
| 537 | | static void mcd212_update_visible_area(running_machine &machine) |
| 515 | void mcd212_device::update_visible_area() |
| 538 | 516 | { |
| 539 | | cdi_state *state = machine.driver_data<cdi_state>(); |
| 540 | | mcd212_regs_t *mcd212 = &state->m_mcd212_regs; |
| 541 | | const rectangle &visarea = machine.primary_screen->visible_area(); |
| 517 | const rectangle &visarea = machine().primary_screen->visible_area(); |
| 542 | 518 | rectangle visarea1; |
| 543 | | attoseconds_t period = machine.primary_screen->frame_period().attoseconds; |
| 519 | attoseconds_t period = machine().primary_screen->frame_period().attoseconds; |
| 544 | 520 | int width = 0; |
| 545 | 521 | |
| 546 | | if((mcd212->channel[0].dcr & (MCD212_DCR_CF | MCD212_DCR_FD)) && (mcd212->channel[0].csrw & MCD212_CSR1W_ST)) |
| 522 | if((m_channel[0].dcr & (MCD212_DCR_CF | MCD212_DCR_FD)) && (m_channel[0].csrw & MCD212_CSR1W_ST)) |
| 547 | 523 | { |
| 548 | 524 | width = 360; |
| 549 | 525 | } |
| r20519 | r20520 | |
| 557 | 533 | visarea1.min_y = visarea.min_y; |
| 558 | 534 | visarea1.max_y = visarea.max_y; |
| 559 | 535 | |
| 560 | | machine.primary_screen->configure(width, 302, visarea1, period); |
| 536 | machine().primary_screen->configure(width, 302, visarea1, period); |
| 561 | 537 | } |
| 562 | 538 | |
| 563 | | static UINT32 mcd212_get_screen_width(mcd212_regs_t *mcd212) |
| 539 | UINT32 mcd212_device::get_screen_width() |
| 564 | 540 | { |
| 565 | | if((mcd212->channel[0].dcr & (MCD212_DCR_CF | MCD212_DCR_FD)) && (mcd212->channel[0].csrw & MCD212_CSR1W_ST)) |
| 541 | if((m_channel[0].dcr & (MCD212_DCR_CF | MCD212_DCR_FD)) && (m_channel[0].csrw & MCD212_CSR1W_ST)) |
| 566 | 542 | { |
| 567 | 543 | return 720; |
| 568 | 544 | } |
| 569 | 545 | return 768; |
| 570 | 546 | } |
| 571 | 547 | |
| 572 | | static void mcd212_process_ica(mcd212_regs_t *mcd212, int channel) |
| 548 | void mcd212_device::process_ica(int channel) |
| 573 | 549 | { |
| 574 | | running_machine &machine = mcd212->machine(); |
| 575 | | cdi_state *state = machine.driver_data<cdi_state>(); |
| 550 | cdi_state *state = machine().driver_data<cdi_state>(); |
| 576 | 551 | UINT16 *ica = channel ? state->m_planeb : state->m_planea; |
| 577 | 552 | UINT32 addr = 0x000400/2; |
| 578 | 553 | UINT32 cmd = 0; |
| r20519 | r20520 | |
| 595 | 570 | case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: // RELOAD DCP |
| 596 | 571 | case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: |
| 597 | 572 | verboselog(machine, 11, "%08x: %08x: ICA %d: RELOAD DCP\n", addr * 2 + channel * 0x200000, cmd, channel ); |
| 598 | | mcd212_set_dcp(mcd212, channel, cmd & 0x001fffff); |
| 573 | set_dcp(channel, cmd & 0x001fffff); |
| 599 | 574 | break; |
| 600 | 575 | case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: // RELOAD DCP and STOP |
| 601 | 576 | case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: |
| 602 | 577 | verboselog(machine, 11, "%08x: %08x: ICA %d: RELOAD DCP and STOP\n", addr * 2 + channel * 0x200000, cmd, channel ); |
| 603 | | mcd212_set_dcp(mcd212, channel, cmd & 0x001fffff); |
| 578 | set_dcp(channel, cmd & 0x001fffff); |
| 604 | 579 | stop = 1; |
| 605 | 580 | break; |
| 606 | 581 | case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: // RELOAD ICA |
| r20519 | r20520 | |
| 611 | 586 | case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: // RELOAD VSR and STOP |
| 612 | 587 | case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: |
| 613 | 588 | verboselog(machine, 11, "%08x: %08x: ICA %d: RELOAD VSR and STOP\n", addr * 2 + channel * 0x200000, cmd, channel ); |
| 614 | | mcd212_set_vsr(mcd212, channel, cmd & 0x001fffff); |
| 589 | set_vsr(channel, cmd & 0x001fffff); |
| 615 | 590 | stop = 1; |
| 616 | 591 | break; |
| 617 | 592 | case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: // INTERRUPT |
| 618 | 593 | case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f: |
| 619 | 594 | verboselog(machine, 11, "%08x: %08x: ICA %d: INTERRUPT\n", addr * 2 + channel * 0x200000, cmd, channel ); |
| 620 | | mcd212->channel[1].csrr |= 1 << (2 - channel); |
| 621 | | if(mcd212->channel[1].csrr & (MCD212_CSR2R_IT1 | MCD212_CSR2R_IT2)) |
| 595 | m_channel[1].csrr |= 1 << (2 - channel); |
| 596 | if(m_channel[1].csrr & (MCD212_CSR2R_IT1 | MCD212_CSR2R_IT2)) |
| 622 | 597 | { |
| 623 | 598 | UINT8 interrupt = (state->m_scc->get_lir() >> 4) & 7; |
| 624 | 599 | if(interrupt) |
| r20519 | r20520 | |
| 628 | 603 | } |
| 629 | 604 | } |
| 630 | 605 | #if 0 |
| 631 | | if(mcd212->channel[1].csrr & MCD212_CSR2R_IT2) |
| 606 | if(m_channel[1].csrr & MCD212_CSR2R_IT2) |
| 632 | 607 | { |
| 633 | 608 | UINT8 interrupt = state->m_scc68070_regs.lir & 7; |
| 634 | 609 | if(interrupt) |
| r20519 | r20520 | |
| 641 | 616 | break; |
| 642 | 617 | case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: // RELOAD DISPLAY PARAMETERS |
| 643 | 618 | verboselog(machine, 6, "%08x: %08x: ICA %d: RELOAD DISPLAY PARAMETERS\n", addr * 2 + channel * 0x200000, cmd, channel ); |
| 644 | | mcd212_set_display_parameters(mcd212, channel, cmd & 0x1f); |
| 619 | set_display_parameters(channel, cmd & 0x1f); |
| 645 | 620 | break; |
| 646 | 621 | default: |
| 647 | | mcd212_set_register(machine, channel, cmd >> 24, cmd & 0x00ffffff); |
| 622 | set_register(channel, cmd >> 24, cmd & 0x00ffffff); |
| 648 | 623 | break; |
| 649 | 624 | } |
| 650 | 625 | if(stop) |
| r20519 | r20520 | |
| 654 | 629 | } |
| 655 | 630 | } |
| 656 | 631 | |
| 657 | | static void mcd212_process_dca(mcd212_regs_t *mcd212, int channel) |
| 632 | void mcd212_device::process_dca(int channel) |
| 658 | 633 | { |
| 659 | | running_machine &machine = mcd212->machine(); |
| 660 | | cdi_state *state = machine.driver_data<cdi_state>(); |
| 634 | cdi_state *state = machine().driver_data<cdi_state>(); |
| 661 | 635 | UINT16 *dca = channel ? state->m_planeb : state->m_planea; |
| 662 | | UINT32 addr = (mcd212->channel[channel].dca & 0x0007ffff) / 2; //(mcd212_get_dcp(mcd212, channel) & 0x0007ffff) / 2; // mcd212->channel[channel].dca / 2; |
| 636 | UINT32 addr = (m_channel[channel].dca & 0x0007ffff) / 2; //(get_dcp(mcd212, channel) & 0x0007ffff) / 2; // m_channel[channel].dca / 2; |
| 663 | 637 | UINT32 cmd = 0; |
| 664 | 638 | UINT32 count = 0; |
| 665 | 639 | UINT32 max = 64; |
| r20519 | r20520 | |
| 689 | 663 | case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: // RELOAD DCP and STOP |
| 690 | 664 | case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: |
| 691 | 665 | verboselog(machine, 11, "%08x: %08x: DCA %d: RELOAD DCP and STOP\n", addr * 2 + channel * 0x200000, cmd, channel ); |
| 692 | | mcd212_set_dcp(&state->m_mcd212_regs, channel, cmd & 0x001fffff); |
| 666 | set_dcp(channel, cmd & 0x001fffff); |
| 693 | 667 | addr = (cmd & 0x0007ffff) / 2; |
| 694 | 668 | addr_changed = 1; |
| 695 | 669 | stop = 1; |
| r20519 | r20520 | |
| 697 | 671 | case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: // RELOAD VSR |
| 698 | 672 | case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: |
| 699 | 673 | verboselog(machine, 11, "%08x: %08x: DCA %d: RELOAD VSR\n", addr * 2 + channel * 0x200000, cmd, channel ); |
| 700 | | mcd212_set_vsr(&state->m_mcd212_regs, channel, cmd & 0x001fffff); |
| 674 | set_vsr(channel, cmd & 0x001fffff); |
| 701 | 675 | break; |
| 702 | 676 | case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: // RELOAD VSR and STOP |
| 703 | 677 | case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: |
| 704 | 678 | verboselog(machine, 11, "%08x: %08x: DCA %d: RELOAD VSR and STOP\n", addr * 2 + channel * 0x200000, cmd, channel ); |
| 705 | | mcd212_set_vsr(&state->m_mcd212_regs, channel, cmd & 0x001fffff); |
| 679 | set_vsr(channel, cmd & 0x001fffff); |
| 706 | 680 | stop = 1; |
| 707 | 681 | break; |
| 708 | 682 | case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: // INTERRUPT |
| 709 | 683 | case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f: |
| 710 | 684 | verboselog(machine, 11, "%08x: %08x: DCA %d: INTERRUPT\n", addr * 2 + channel * 0x200000, cmd, channel ); |
| 711 | | mcd212->channel[1].csrr |= 1 << (2 - channel); |
| 712 | | if(mcd212->channel[1].csrr & (MCD212_CSR2R_IT1 | MCD212_CSR2R_IT2)) |
| 685 | m_channel[1].csrr |= 1 << (2 - channel); |
| 686 | if(m_channel[1].csrr & (MCD212_CSR2R_IT1 | MCD212_CSR2R_IT2)) |
| 713 | 687 | { |
| 714 | 688 | UINT8 interrupt = (state->m_scc->get_lir() >> 4) & 7; |
| 715 | 689 | if(interrupt) |
| r20519 | r20520 | |
| 719 | 693 | } |
| 720 | 694 | } |
| 721 | 695 | #if 0 |
| 722 | | if(mcd212->channel[1].csrr & MCD212_CSR2R_IT2) |
| 696 | if(m_channel[1].csrr & MCD212_CSR2R_IT2) |
| 723 | 697 | { |
| 724 | 698 | UINT8 interrupt = state->m_scc68070_regs.lir & 7; |
| 725 | 699 | if(interrupt) |
| r20519 | r20520 | |
| 732 | 706 | break; |
| 733 | 707 | case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: // RELOAD DISPLAY PARAMETERS |
| 734 | 708 | verboselog(machine, 6, "%08x: %08x: DCA %d: RELOAD DISPLAY PARAMETERS\n", addr * 2 + channel * 0x200000, cmd, channel ); |
| 735 | | mcd212_set_display_parameters(&state->m_mcd212_regs, channel, cmd & 0x1f); |
| 709 | set_display_parameters(channel, cmd & 0x1f); |
| 736 | 710 | break; |
| 737 | 711 | default: |
| 738 | | mcd212_set_register(machine, channel, cmd >> 24, cmd & 0x00ffffff); |
| 712 | set_register(channel, cmd >> 24, cmd & 0x00ffffff); |
| 739 | 713 | break; |
| 740 | 714 | } |
| 741 | 715 | if(stop != 0 || count == max) |
| r20519 | r20520 | |
| 750 | 724 | addr += (max - count) >> 1; |
| 751 | 725 | } |
| 752 | 726 | } |
| 753 | | mcd212->channel[channel].dca = addr * 2; |
| 727 | m_channel[channel].dca = addr * 2; |
| 754 | 728 | } |
| 755 | 729 | |
| 756 | 730 | INLINE UINT8 MCD212_LIM(INT32 in) |
| r20519 | r20520 | |
| 802 | 776 | return 0; |
| 803 | 777 | } |
| 804 | 778 | |
| 805 | | static void mcd212_process_vsr(mcd212_regs_t *mcd212, int channel, UINT8 *pixels_r, UINT8 *pixels_g, UINT8 *pixels_b) |
| 779 | void mcd212_device::process_vsr(int channel, UINT8 *pixels_r, UINT8 *pixels_g, UINT8 *pixels_b) |
| 806 | 780 | { |
| 807 | | running_machine &machine = mcd212->machine(); |
| 808 | | cdi_state *state = machine.driver_data<cdi_state>(); |
| 781 | cdi_state *state = machine().driver_data<cdi_state>(); |
| 809 | 782 | UINT8 *data = reinterpret_cast<UINT8 *>(channel ? state->m_planeb.target() : state->m_planea.target()); |
| 810 | | UINT32 vsr = mcd212_get_vsr(mcd212, channel) & 0x0007ffff; |
| 783 | UINT32 vsr = get_vsr(channel) & 0x0007ffff; |
| 811 | 784 | UINT8 done = 0; |
| 812 | 785 | UINT32 x = 0; |
| 813 | 786 | UINT32 icm_mask = channel ? MCD212_ICM_MODE2 : MCD212_ICM_MODE1; |
| 814 | 787 | UINT32 icm_shift = channel ? MCD212_ICM_MODE2_SHIFT : MCD212_ICM_MODE1_SHIFT; |
| 815 | | UINT8 icm = (mcd212->channel[0].image_coding_method & icm_mask) >> icm_shift; |
| 816 | | UINT8 *clut_r = mcd212->channel[0].clut_r; |
| 817 | | UINT8 *clut_g = mcd212->channel[0].clut_g; |
| 818 | | UINT8 *clut_b = mcd212->channel[0].clut_b; |
| 819 | | UINT8 mosaic_enable = ((mcd212->channel[channel].ddr & MCD212_DDR_FT) == MCD212_DDR_FT_MOSAIC); |
| 820 | | UINT8 mosaic_factor = 1 << (((mcd212->channel[channel].ddr & MCD212_DDR_MT) >> MCD212_DDR_MT_SHIFT) + 1); |
| 788 | UINT8 icm = (m_channel[0].image_coding_method & icm_mask) >> icm_shift; |
| 789 | UINT8 *clut_r = m_channel[0].clut_r; |
| 790 | UINT8 *clut_g = m_channel[0].clut_g; |
| 791 | UINT8 *clut_b = m_channel[0].clut_b; |
| 792 | UINT8 mosaic_enable = ((m_channel[channel].ddr & MCD212_DDR_FT) == MCD212_DDR_FT_MOSAIC); |
| 793 | UINT8 mosaic_factor = 1 << (((m_channel[channel].ddr & MCD212_DDR_MT) >> MCD212_DDR_MT_SHIFT) + 1); |
| 821 | 794 | int mosaic_index = 0; |
| 822 | | UINT32 width = mcd212_get_screen_width(mcd212); |
| 795 | UINT32 width = get_screen_width(); |
| 823 | 796 | |
| 824 | 797 | //printf( "vsr before: %08x: ", vsr ); |
| 825 | 798 | //fflush(stdout); |
| r20519 | r20520 | |
| 836 | 809 | { |
| 837 | 810 | UINT8 byte = data[(vsr & 0x0007ffff) ^ 1]; |
| 838 | 811 | vsr++; |
| 839 | | switch(mcd212->channel[channel].ddr & MCD212_DDR_FT) |
| 812 | switch(m_channel[channel].ddr & MCD212_DDR_FT) |
| 840 | 813 | { |
| 841 | 814 | case MCD212_DDR_FT_BMP: |
| 842 | 815 | case MCD212_DDR_FT_BMP2: |
| 843 | 816 | case MCD212_DDR_FT_MOSAIC: |
| 844 | | if(mcd212->channel[channel].dcr & MCD212_DCR_CM) |
| 817 | if(m_channel[channel].dcr & MCD212_DCR_CM) |
| 845 | 818 | { |
| 846 | 819 | // 4-bit Bitmap |
| 847 | 820 | verboselog(machine, 0, "Unsupported display mode: 4-bit Bitmap\n" ); |
| r20519 | r20520 | |
| 857 | 830 | switch(channel) |
| 858 | 831 | { |
| 859 | 832 | case 0: |
| 860 | | bY = (mcd212->channel[0].dyuv_abs_start_a >> 16) & 0x000000ff; |
| 861 | | bU = (mcd212->channel[0].dyuv_abs_start_a >> 8) & 0x000000ff; |
| 862 | | bV = (mcd212->channel[0].dyuv_abs_start_a >> 0) & 0x000000ff; |
| 833 | bY = (m_channel[0].dyuv_abs_start_a >> 16) & 0x000000ff; |
| 834 | bU = (m_channel[0].dyuv_abs_start_a >> 8) & 0x000000ff; |
| 835 | bV = (m_channel[0].dyuv_abs_start_a >> 0) & 0x000000ff; |
| 863 | 836 | break; |
| 864 | 837 | case 1: |
| 865 | | bY = (mcd212->channel[1].dyuv_abs_start_b >> 16) & 0x000000ff; |
| 866 | | bU = (mcd212->channel[1].dyuv_abs_start_b >> 8) & 0x000000ff; |
| 867 | | bV = (mcd212->channel[1].dyuv_abs_start_b >> 0) & 0x000000ff; |
| 838 | bY = (m_channel[1].dyuv_abs_start_b >> 16) & 0x000000ff; |
| 839 | bU = (m_channel[1].dyuv_abs_start_b >> 8) & 0x000000ff; |
| 840 | bV = (m_channel[1].dyuv_abs_start_b >> 0) & 0x000000ff; |
| 868 | 841 | break; |
| 869 | 842 | default: |
| 870 | 843 | bY = bU = bV = 0x80; |
| r20519 | r20520 | |
| 873 | 846 | for(; x < width; x += 2) |
| 874 | 847 | { |
| 875 | 848 | BYTE68K b0 = byte; |
| 876 | | BYTE68K bU1 = bU + state->m_mcd212_ab.deltaUV[b0]; |
| 877 | | BYTE68K bY0 = bY + state->m_mcd212_ab.deltaY[b0]; |
| 849 | BYTE68K bU1 = bU + m_ab.deltaUV[b0]; |
| 850 | BYTE68K bY0 = bY + m_ab.deltaY[b0]; |
| 878 | 851 | |
| 879 | 852 | BYTE68K b1 = data[(vsr & 0x0007ffff) ^ 1]; |
| 880 | | BYTE68K bV1 = bV + state->m_mcd212_ab.deltaUV[b1]; |
| 881 | | BYTE68K bY1 = bY0 + state->m_mcd212_ab.deltaY[b1]; |
| 853 | BYTE68K bV1 = bV + m_ab.deltaUV[b1]; |
| 854 | BYTE68K bY1 = bY0 + m_ab.deltaY[b1]; |
| 882 | 855 | |
| 883 | 856 | BYTE68K bU0 = (bU + bU1) >> 1; |
| 884 | 857 | BYTE68K bV0 = (bV + bV1) >> 1; |
| r20519 | r20520 | |
| 891 | 864 | bU = bU0; |
| 892 | 865 | bV = bV0; |
| 893 | 866 | |
| 894 | | pbLimit = state->m_mcd212_ab.limit + bY + BYTE68K_MAX; |
| 867 | pbLimit = m_ab.limit + bY + BYTE68K_MAX; |
| 895 | 868 | |
| 896 | | pixels_r[x + 0] = pixels_r[x + 1] = pbLimit[state->m_mcd212_ab.matrixVR[bV]]; |
| 897 | | pixels_g[x + 0] = pixels_g[x + 1] = pbLimit[state->m_mcd212_ab.matrixUG[bU] + state->m_mcd212_ab.matrixVG[bV]]; |
| 898 | | pixels_b[x + 0] = pixels_b[x + 1] = pbLimit[state->m_mcd212_ab.matrixUB[bU]]; |
| 869 | pixels_r[x + 0] = pixels_r[x + 1] = pbLimit[m_ab.matrixVR[bV]]; |
| 870 | pixels_g[x + 0] = pixels_g[x + 1] = pbLimit[m_ab.matrixUG[bU] + m_ab.matrixVG[bV]]; |
| 871 | pixels_b[x + 0] = pixels_b[x + 1] = pbLimit[m_ab.matrixUB[bU]]; |
| 899 | 872 | |
| 900 | 873 | if(mosaic_enable) |
| 901 | 874 | { |
| r20519 | r20520 | |
| 919 | 892 | bU = bU1; |
| 920 | 893 | bV = bV1; |
| 921 | 894 | |
| 922 | | pbLimit = state->m_mcd212_ab.limit + bY + BYTE68K_MAX; |
| 895 | pbLimit = m_ab.limit + bY + BYTE68K_MAX; |
| 923 | 896 | |
| 924 | | pixels_r[x + 0] = pixels_r[x + 1] = pbLimit[state->m_mcd212_ab.matrixVR[bV]]; |
| 925 | | pixels_g[x + 0] = pixels_g[x + 1] = pbLimit[state->m_mcd212_ab.matrixUG[bU] + state->m_mcd212_ab.matrixVG[bV]]; |
| 926 | | pixels_b[x + 0] = pixels_b[x + 1] = pbLimit[state->m_mcd212_ab.matrixUB[bU]]; |
| 897 | pixels_r[x + 0] = pixels_r[x + 1] = pbLimit[m_ab.matrixVR[bV]]; |
| 898 | pixels_g[x + 0] = pixels_g[x + 1] = pbLimit[m_ab.matrixUG[bU] + m_ab.matrixVG[bV]]; |
| 899 | pixels_b[x + 0] = pixels_b[x + 1] = pbLimit[m_ab.matrixUB[bU]]; |
| 927 | 900 | |
| 928 | 901 | if(mosaic_enable) |
| 929 | 902 | { |
| r20519 | r20520 | |
| 943 | 916 | |
| 944 | 917 | vsr++; |
| 945 | 918 | } |
| 946 | | mcd212_set_vsr(&state->m_mcd212_regs, channel, (vsr - 1) & 0x0007ffff); |
| 919 | set_vsr(channel, (vsr - 1) & 0x0007ffff); |
| 947 | 920 | } |
| 948 | 921 | else if(icm == 1 || icm == 3 || icm == 4) |
| 949 | 922 | { |
| r20519 | r20520 | |
| 972 | 945 | byte = data[(vsr & 0x0007ffff) ^ 1]; |
| 973 | 946 | vsr++; |
| 974 | 947 | } |
| 975 | | mcd212_set_vsr(&state->m_mcd212_regs, channel, (vsr - 1) & 0x0007ffff); |
| 948 | set_vsr(channel, (vsr - 1) & 0x0007ffff); |
| 976 | 949 | } |
| 977 | 950 | else if(icm == 11) |
| 978 | 951 | { |
| r20519 | r20520 | |
| 1008 | 981 | byte = data[(vsr & 0x0007ffff) ^ 1]; |
| 1009 | 982 | vsr++; |
| 1010 | 983 | } |
| 1011 | | mcd212_set_vsr(&state->m_mcd212_regs, channel, (vsr - 1) & 0x0007ffff); |
| 984 | set_vsr(channel, (vsr - 1) & 0x0007ffff); |
| 1012 | 985 | } |
| 1013 | 986 | else |
| 1014 | 987 | { |
| r20519 | r20520 | |
| 1023 | 996 | done = 1; |
| 1024 | 997 | break; |
| 1025 | 998 | case MCD212_DDR_FT_RLE: |
| 1026 | | if(mcd212->channel[channel].dcr & MCD212_DCR_CM) |
| 999 | if(m_channel[channel].dcr & MCD212_DCR_CM) |
| 1027 | 1000 | { |
| 1028 | 1001 | verboselog(machine, 0, "Unsupported display mode: 4-bit RLE\n" ); |
| 1029 | 1002 | done = 1; |
| r20519 | r20520 | |
| 1052 | 1025 | pixels_b[x] = b; |
| 1053 | 1026 | } |
| 1054 | 1027 | done = 1; |
| 1055 | | mcd212_set_vsr(&state->m_mcd212_regs, channel, vsr); |
| 1028 | set_vsr(channel, vsr); |
| 1056 | 1029 | } |
| 1057 | 1030 | else |
| 1058 | 1031 | { |
| r20519 | r20520 | |
| 1074 | 1047 | if(x >= width) |
| 1075 | 1048 | { |
| 1076 | 1049 | done = 1; |
| 1077 | | mcd212_set_vsr(&state->m_mcd212_regs, channel, vsr); |
| 1050 | set_vsr(channel, vsr); |
| 1078 | 1051 | } |
| 1079 | 1052 | } |
| 1080 | 1053 | } |
| r20519 | r20520 | |
| 1093 | 1066 | if(x >= width) |
| 1094 | 1067 | { |
| 1095 | 1068 | done = 1; |
| 1096 | | mcd212_set_vsr(&state->m_mcd212_regs, channel, vsr); |
| 1069 | set_vsr(channel, vsr); |
| 1097 | 1070 | } |
| 1098 | 1071 | } |
| 1099 | 1072 | } |
| r20519 | r20520 | |
| 1105 | 1078 | //mcd212_set_vsr(&state->m_mcd212_regs, channel, vsr); |
| 1106 | 1079 | } |
| 1107 | 1080 | |
| 1108 | | static const UINT32 mcd212_4bpp_color[16] = |
| 1081 | const UINT32 mcd212_device::s_4bpp_color[16] = |
| 1109 | 1082 | { |
| 1110 | 1083 | 0x00101010, 0x0010107a, 0x00107a10, 0x00107a7a, 0x007a1010, 0x007a107a, 0x007a7a10, 0x007a7a7a, |
| 1111 | 1084 | 0x00101010, 0x001010e6, 0x0010e610, 0x0010e6e6, 0x00e61010, 0x00e610e6, 0x00e6e610, 0x00e6e6e6 |
| 1112 | 1085 | }; |
| 1113 | 1086 | |
| 1114 | | static void mcd212_mix_lines(mcd212_regs_t *mcd212, UINT8 *plane_a_r, UINT8 *plane_a_g, UINT8 *plane_a_b, UINT8 *plane_b_r, UINT8 *plane_b_g, UINT8 *plane_b_b, UINT32 *out) |
| 1087 | void mcd212_device::mix_lines(UINT8 *plane_a_r, UINT8 *plane_a_g, UINT8 *plane_a_b, UINT8 *plane_b_r, UINT8 *plane_b_g, UINT8 *plane_b_b, UINT32 *out) |
| 1115 | 1088 | { |
| 1116 | | running_machine &machine = mcd212->machine(); |
| 1117 | | int x = 0; |
| 1118 | | UINT8 debug_mode = machine.root_device().ioport("DEBUG")->read(); |
| 1089 | UINT8 debug_mode = machine().root_device().ioport("DEBUG")->read(); |
| 1119 | 1090 | UINT8 global_plane_a_disable = debug_mode & 1; |
| 1120 | 1091 | UINT8 global_plane_b_disable = debug_mode & 2; |
| 1121 | 1092 | UINT8 debug_backdrop_enable = debug_mode & 4; |
| 1122 | 1093 | UINT8 debug_backdrop_index = debug_mode >> 4; |
| 1123 | | UINT32 backdrop = debug_backdrop_enable ? mcd212_4bpp_color[debug_backdrop_index] : mcd212_4bpp_color[mcd212->channel[0].backdrop_color]; |
| 1124 | | UINT8 transparency_mode_a = (mcd212->channel[0].transparency_control >> 0) & 0x0f; |
| 1125 | | UINT8 transparency_mode_b = (mcd212->channel[0].transparency_control >> 8) & 0x0f; |
| 1126 | | UINT8 transparent_color_a_r = (UINT8)(mcd212->channel[0].transparent_color_a >> 16); |
| 1127 | | UINT8 transparent_color_a_g = (UINT8)(mcd212->channel[0].transparent_color_a >> 8); |
| 1128 | | UINT8 transparent_color_a_b = (UINT8)(mcd212->channel[0].transparent_color_a >> 0); |
| 1129 | | UINT8 transparent_color_b_r = (UINT8)(mcd212->channel[1].transparent_color_b >> 16); |
| 1130 | | UINT8 transparent_color_b_g = (UINT8)(mcd212->channel[1].transparent_color_b >> 8); |
| 1131 | | UINT8 transparent_color_b_b = (UINT8)(mcd212->channel[1].transparent_color_b >> 0); |
| 1132 | | UINT8 image_coding_method_a = mcd212->channel[0].image_coding_method & 0x0000000f; |
| 1133 | | UINT8 image_coding_method_b = (mcd212->channel[0].image_coding_method >> 8) & 0x0000000f; |
| 1134 | | UINT8 dyuv_enable_a = (image_coding_method_a == 5); |
| 1135 | | UINT8 dyuv_enable_b = (image_coding_method_b == 5); |
| 1136 | | UINT8 mosaic_enable_a = (mcd212->channel[0].mosaic_hold_a & 0x800000) >> 23; |
| 1137 | | UINT8 mosaic_enable_b = (mcd212->channel[1].mosaic_hold_b & 0x800000) >> 23; |
| 1138 | | UINT8 mosaic_count_a = (mcd212->channel[0].mosaic_hold_a & 0x0000ff) << 1; |
| 1139 | | UINT8 mosaic_count_b = (mcd212->channel[1].mosaic_hold_b & 0x0000ff) << 1; |
| 1140 | | for(x = 0; x < 768; x++) |
| 1094 | UINT32 backdrop = debug_backdrop_enable ? s_4bpp_color[debug_backdrop_index] : s_4bpp_color[m_channel[0].backdrop_color]; |
| 1095 | UINT8 transparency_mode_a = (m_channel[0].transparency_control >> 0) & 0x0f; |
| 1096 | UINT8 transparency_mode_b = (m_channel[0].transparency_control >> 8) & 0x0f; |
| 1097 | UINT8 transparent_color_a_r = (UINT8)(m_channel[0].transparent_color_a >> 16); |
| 1098 | UINT8 transparent_color_a_g = (UINT8)(m_channel[0].transparent_color_a >> 8); |
| 1099 | UINT8 transparent_color_a_b = (UINT8)(m_channel[0].transparent_color_a >> 0); |
| 1100 | UINT8 transparent_color_b_r = (UINT8)(m_channel[1].transparent_color_b >> 16); |
| 1101 | UINT8 transparent_color_b_g = (UINT8)(m_channel[1].transparent_color_b >> 8); |
| 1102 | UINT8 transparent_color_b_b = (UINT8)(m_channel[1].transparent_color_b >> 0); |
| 1103 | UINT8 image_coding_method_a = m_channel[0].image_coding_method & 0x0000000f; |
| 1104 | UINT8 image_coding_method_b = (m_channel[0].image_coding_method >> 8) & 0x0000000f; |
| 1105 | bool dyuv_enable_a = (image_coding_method_a == 5); |
| 1106 | bool dyuv_enable_b = (image_coding_method_b == 5); |
| 1107 | UINT8 mosaic_enable_a = (m_channel[0].mosaic_hold_a & 0x800000) >> 23; |
| 1108 | UINT8 mosaic_enable_b = (m_channel[1].mosaic_hold_b & 0x800000) >> 23; |
| 1109 | UINT8 mosaic_count_a = (m_channel[0].mosaic_hold_a & 0x0000ff) << 1; |
| 1110 | UINT8 mosaic_count_b = (m_channel[1].mosaic_hold_b & 0x0000ff) << 1; |
| 1111 | for(int x = 0; x < 768; x++) |
| 1141 | 1112 | { |
| 1142 | 1113 | out[x] = backdrop; |
| 1143 | | if(!(mcd212->channel[0].transparency_control & MCD212_TCR_DISABLE_MX)) |
| 1114 | if(!(m_channel[0].transparency_control & MCD212_TCR_DISABLE_MX)) |
| 1144 | 1115 | { |
| 1145 | | UINT8 abr = MCD212_LIM(((MCD212_LIM((INT32)plane_a_r[x] - 16) * mcd212->channel[0].weight_factor_a[x]) >> 6) + ((MCD212_LIM((INT32)plane_b_r[x] - 16) * mcd212->channel[1].weight_factor_b[x]) >> 6) + 16); |
| 1146 | | UINT8 abg = MCD212_LIM(((MCD212_LIM((INT32)plane_a_g[x] - 16) * mcd212->channel[0].weight_factor_a[x]) >> 6) + ((MCD212_LIM((INT32)plane_b_g[x] - 16) * mcd212->channel[1].weight_factor_b[x]) >> 6) + 16); |
| 1147 | | UINT8 abb = MCD212_LIM(((MCD212_LIM((INT32)plane_a_b[x] - 16) * mcd212->channel[0].weight_factor_a[x]) >> 6) + ((MCD212_LIM((INT32)plane_b_b[x] - 16) * mcd212->channel[1].weight_factor_b[x]) >> 6) + 16); |
| 1116 | UINT8 abr = MCD212_LIM(((MCD212_LIM((INT32)plane_a_r[x] - 16) * m_channel[0].weight_factor_a[x]) >> 6) + ((MCD212_LIM((INT32)plane_b_r[x] - 16) * m_channel[1].weight_factor_b[x]) >> 6) + 16); |
| 1117 | UINT8 abg = MCD212_LIM(((MCD212_LIM((INT32)plane_a_g[x] - 16) * m_channel[0].weight_factor_a[x]) >> 6) + ((MCD212_LIM((INT32)plane_b_g[x] - 16) * m_channel[1].weight_factor_b[x]) >> 6) + 16); |
| 1118 | UINT8 abb = MCD212_LIM(((MCD212_LIM((INT32)plane_a_b[x] - 16) * m_channel[0].weight_factor_a[x]) >> 6) + ((MCD212_LIM((INT32)plane_b_b[x] - 16) * m_channel[1].weight_factor_b[x]) >> 6) + 16); |
| 1148 | 1119 | out[x] = (abr << 16) | (abg << 8) | abb; |
| 1149 | 1120 | } |
| 1150 | 1121 | else |
| r20519 | r20520 | |
| 1166 | 1137 | plane_enable_a = (plane_a_r_cur != transparent_color_a_r || plane_a_g_cur != transparent_color_a_g || plane_a_b_cur != transparent_color_a_b); |
| 1167 | 1138 | break; |
| 1168 | 1139 | case 3: |
| 1169 | | plane_enable_a = !mcd212->region_flag_0[x]; |
| 1140 | plane_enable_a = !m_region_flag_0[x]; |
| 1170 | 1141 | break; |
| 1171 | 1142 | case 4: |
| 1172 | | plane_enable_a = !mcd212->region_flag_1[x]; |
| 1143 | plane_enable_a = !m_region_flag_1[x]; |
| 1173 | 1144 | break; |
| 1174 | 1145 | case 5: |
| 1175 | | plane_enable_a = (plane_a_r_cur != transparent_color_a_r || plane_a_g_cur != transparent_color_a_g || plane_a_b_cur != transparent_color_a_b) && (dyuv_enable_a || mcd212->region_flag_0[x] == 0); |
| 1146 | plane_enable_a = (plane_a_r_cur != transparent_color_a_r || plane_a_g_cur != transparent_color_a_g || plane_a_b_cur != transparent_color_a_b) && (dyuv_enable_a || m_region_flag_0[x] == 0); |
| 1176 | 1147 | break; |
| 1177 | 1148 | case 6: |
| 1178 | | plane_enable_a = (plane_a_r_cur != transparent_color_a_r || plane_a_g_cur != transparent_color_a_g || plane_a_b_cur != transparent_color_a_b) && (dyuv_enable_a || mcd212->region_flag_1[x] == 0); |
| 1149 | plane_enable_a = (plane_a_r_cur != transparent_color_a_r || plane_a_g_cur != transparent_color_a_g || plane_a_b_cur != transparent_color_a_b) && (dyuv_enable_a || m_region_flag_1[x] == 0); |
| 1179 | 1150 | break; |
| 1180 | 1151 | case 8: |
| 1181 | 1152 | plane_enable_a = 1; |
| r20519 | r20520 | |
| 1184 | 1155 | plane_enable_a = (plane_a_r_cur == transparent_color_a_r && plane_a_g_cur == transparent_color_a_g && plane_a_b_cur == transparent_color_a_b); |
| 1185 | 1156 | break; |
| 1186 | 1157 | case 11: |
| 1187 | | plane_enable_a = mcd212->region_flag_0[x]; |
| 1158 | plane_enable_a = m_region_flag_0[x]; |
| 1188 | 1159 | break; |
| 1189 | 1160 | case 12: |
| 1190 | | plane_enable_a = mcd212->region_flag_1[x]; |
| 1161 | plane_enable_a = m_region_flag_1[x]; |
| 1191 | 1162 | break; |
| 1192 | 1163 | case 13: |
| 1193 | | plane_enable_a = (plane_a_r_cur == transparent_color_a_r && plane_a_g_cur == transparent_color_a_g && plane_a_b_cur == transparent_color_a_b) || dyuv_enable_a || mcd212->region_flag_0[x] == 1; |
| 1164 | plane_enable_a = (plane_a_r_cur == transparent_color_a_r && plane_a_g_cur == transparent_color_a_g && plane_a_b_cur == transparent_color_a_b) || dyuv_enable_a || m_region_flag_0[x] == 1; |
| 1194 | 1165 | break; |
| 1195 | 1166 | case 14: |
| 1196 | | plane_enable_a = (plane_a_r_cur == transparent_color_a_r && plane_a_g_cur == transparent_color_a_g && plane_a_b_cur == transparent_color_a_b) || dyuv_enable_a || mcd212->region_flag_1[x] == 1; |
| 1167 | plane_enable_a = (plane_a_r_cur == transparent_color_a_r && plane_a_g_cur == transparent_color_a_g && plane_a_b_cur == transparent_color_a_b) || dyuv_enable_a || m_region_flag_1[x] == 1; |
| 1197 | 1168 | break; |
| 1198 | 1169 | default: |
| 1199 | 1170 | verboselog(machine, 0, "Unhandled transparency mode for plane A: %d\n", transparency_mode_a); |
| r20519 | r20520 | |
| 1209 | 1180 | plane_enable_b = (plane_b_r_cur != transparent_color_b_r || plane_b_g_cur != transparent_color_b_g || plane_b_b_cur != transparent_color_b_b); |
| 1210 | 1181 | break; |
| 1211 | 1182 | case 3: |
| 1212 | | plane_enable_b = !mcd212->region_flag_0[x]; |
| 1183 | plane_enable_b = !m_region_flag_0[x]; |
| 1213 | 1184 | break; |
| 1214 | 1185 | case 4: |
| 1215 | | plane_enable_b = !mcd212->region_flag_1[x]; |
| 1186 | plane_enable_b = !m_region_flag_1[x]; |
| 1216 | 1187 | break; |
| 1217 | 1188 | case 5: |
| 1218 | | plane_enable_b = (plane_b_r_cur != transparent_color_b_r || plane_b_g_cur != transparent_color_b_g || plane_b_b_cur != transparent_color_b_b) && (dyuv_enable_b || mcd212->region_flag_0[x] == 0); |
| 1189 | plane_enable_b = (plane_b_r_cur != transparent_color_b_r || plane_b_g_cur != transparent_color_b_g || plane_b_b_cur != transparent_color_b_b) && (dyuv_enable_b || m_region_flag_0[x] == 0); |
| 1219 | 1190 | break; |
| 1220 | 1191 | case 6: |
| 1221 | | plane_enable_b = (plane_b_r_cur != transparent_color_b_r || plane_b_g_cur != transparent_color_b_g || plane_b_b_cur != transparent_color_b_b) && (dyuv_enable_b || mcd212->region_flag_1[x] == 0); |
| 1192 | plane_enable_b = (plane_b_r_cur != transparent_color_b_r || plane_b_g_cur != transparent_color_b_g || plane_b_b_cur != transparent_color_b_b) && (dyuv_enable_b || m_region_flag_1[x] == 0); |
| 1222 | 1193 | break; |
| 1223 | 1194 | case 8: |
| 1224 | 1195 | plane_enable_b = 1; |
| r20519 | r20520 | |
| 1227 | 1198 | plane_enable_b = (plane_b_r_cur == transparent_color_b_r && plane_b_g_cur == transparent_color_b_g && plane_b_b_cur == transparent_color_b_b); |
| 1228 | 1199 | break; |
| 1229 | 1200 | case 11: |
| 1230 | | plane_enable_b = mcd212->region_flag_0[x]; |
| 1201 | plane_enable_b = m_region_flag_0[x]; |
| 1231 | 1202 | break; |
| 1232 | 1203 | case 12: |
| 1233 | | plane_enable_b = mcd212->region_flag_1[x]; |
| 1204 | plane_enable_b = m_region_flag_1[x]; |
| 1234 | 1205 | break; |
| 1235 | 1206 | case 13: |
| 1236 | | plane_enable_b = (plane_b_r_cur == transparent_color_b_r && plane_b_g_cur == transparent_color_b_g && plane_b_b_cur == transparent_color_b_b) || dyuv_enable_b || mcd212->region_flag_0[x] == 1; |
| 1207 | plane_enable_b = (plane_b_r_cur == transparent_color_b_r && plane_b_g_cur == transparent_color_b_g && plane_b_b_cur == transparent_color_b_b) || dyuv_enable_b || m_region_flag_0[x] == 1; |
| 1237 | 1208 | break; |
| 1238 | 1209 | case 14: |
| 1239 | | plane_enable_b = (plane_b_r_cur == transparent_color_b_r && plane_b_g_cur == transparent_color_b_g && plane_b_b_cur == transparent_color_b_b) || dyuv_enable_b || mcd212->region_flag_1[x] == 1; |
| 1210 | plane_enable_b = (plane_b_r_cur == transparent_color_b_r && plane_b_g_cur == transparent_color_b_g && plane_b_b_cur == transparent_color_b_b) || dyuv_enable_b || m_region_flag_1[x] == 1; |
| 1240 | 1211 | break; |
| 1241 | 1212 | default: |
| 1242 | 1213 | verboselog(machine, 0, "Unhandled transparency mode for plane B: %d\n", transparency_mode_b); |
| r20519 | r20520 | |
| 1251 | 1222 | { |
| 1252 | 1223 | plane_enable_b = 0; |
| 1253 | 1224 | } |
| 1254 | | plane_a_r_cur = MCD212_LIM(((MCD212_LIM((INT32)plane_a_r_cur - 16) * mcd212->channel[0].weight_factor_a[x]) >> 6) + 16); |
| 1255 | | plane_a_g_cur = MCD212_LIM(((MCD212_LIM((INT32)plane_a_g_cur - 16) * mcd212->channel[0].weight_factor_a[x]) >> 6) + 16); |
| 1256 | | plane_a_b_cur = MCD212_LIM(((MCD212_LIM((INT32)plane_a_b_cur - 16) * mcd212->channel[0].weight_factor_a[x]) >> 6) + 16); |
| 1257 | | plane_b_r_cur = MCD212_LIM(((MCD212_LIM((INT32)plane_b_r_cur - 16) * mcd212->channel[1].weight_factor_b[x]) >> 6) + 16); |
| 1258 | | plane_b_g_cur = MCD212_LIM(((MCD212_LIM((INT32)plane_b_g_cur - 16) * mcd212->channel[1].weight_factor_b[x]) >> 6) + 16); |
| 1259 | | plane_b_b_cur = MCD212_LIM(((MCD212_LIM((INT32)plane_b_b_cur - 16) * mcd212->channel[1].weight_factor_b[x]) >> 6) + 16); |
| 1260 | | switch(mcd212->channel[0].plane_order) |
| 1225 | plane_a_r_cur = MCD212_LIM(((MCD212_LIM((INT32)plane_a_r_cur - 16) * m_channel[0].weight_factor_a[x]) >> 6) + 16); |
| 1226 | plane_a_g_cur = MCD212_LIM(((MCD212_LIM((INT32)plane_a_g_cur - 16) * m_channel[0].weight_factor_a[x]) >> 6) + 16); |
| 1227 | plane_a_b_cur = MCD212_LIM(((MCD212_LIM((INT32)plane_a_b_cur - 16) * m_channel[0].weight_factor_a[x]) >> 6) + 16); |
| 1228 | plane_b_r_cur = MCD212_LIM(((MCD212_LIM((INT32)plane_b_r_cur - 16) * m_channel[1].weight_factor_b[x]) >> 6) + 16); |
| 1229 | plane_b_g_cur = MCD212_LIM(((MCD212_LIM((INT32)plane_b_g_cur - 16) * m_channel[1].weight_factor_b[x]) >> 6) + 16); |
| 1230 | plane_b_b_cur = MCD212_LIM(((MCD212_LIM((INT32)plane_b_b_cur - 16) * m_channel[1].weight_factor_b[x]) >> 6) + 16); |
| 1231 | switch(m_channel[0].plane_order) |
| 1261 | 1232 | { |
| 1262 | 1233 | case MCD212_POR_AB: |
| 1263 | 1234 | if(plane_enable_a) |
| r20519 | r20520 | |
| 1284 | 1255 | } |
| 1285 | 1256 | } |
| 1286 | 1257 | |
| 1287 | | static void mcd212_draw_cursor(mcd212_regs_t *mcd212, UINT32 *scanline, int y) |
| 1258 | void mcd212_device::draw_cursor(UINT32 *scanline, int y) |
| 1288 | 1259 | { |
| 1289 | | if(mcd212->channel[0].cursor_control & MCD212_CURCNT_EN) |
| 1260 | if(m_channel[0].cursor_control & MCD212_CURCNT_EN) |
| 1290 | 1261 | { |
| 1291 | | UINT16 curx = mcd212->channel[0].cursor_position & 0x3ff; |
| 1292 | | UINT16 cury = ((mcd212->channel[0].cursor_position >> 12) & 0x3ff) + 22; |
| 1293 | | UINT32 x = 0; |
| 1262 | UINT16 curx = m_channel[0].cursor_position & 0x3ff; |
| 1263 | UINT16 cury = ((m_channel[0].cursor_position >> 12) & 0x3ff) + 22; |
| 1294 | 1264 | if(y >= cury && y < (cury + 16)) |
| 1295 | 1265 | { |
| 1296 | | UINT32 color = mcd212_4bpp_color[mcd212->channel[0].cursor_control & MCD212_CURCNT_COLOR]; |
| 1266 | UINT32 color = s_4bpp_color[m_channel[0].cursor_control & MCD212_CURCNT_COLOR]; |
| 1297 | 1267 | y -= cury; |
| 1298 | | if(mcd212->channel[0].cursor_control & MCD212_CURCNT_CUW) |
| 1268 | if(m_channel[0].cursor_control & MCD212_CURCNT_CUW) |
| 1299 | 1269 | { |
| 1300 | | for(x = curx; x < curx + 64 && x < 768; x++) |
| 1270 | for(int x = curx; x < curx + 64 && x < 768; x++) |
| 1301 | 1271 | { |
| 1302 | | if(mcd212->channel[0].cursor_pattern[y] & (1 << (15 - ((x - curx) >> 2)))) |
| 1272 | if(m_channel[0].cursor_pattern[y] & (1 << (15 - ((x - curx) >> 2)))) |
| 1303 | 1273 | { |
| 1304 | 1274 | scanline[(x++)/2] = color; |
| 1305 | 1275 | scanline[(x++)/2] = color; |
| r20519 | r20520 | |
| 1313 | 1283 | } |
| 1314 | 1284 | else |
| 1315 | 1285 | { |
| 1316 | | for(x = curx; x < curx + 32 && x < 768; x++) |
| 1286 | for(int x = curx; x < curx + 32 && x < 768; x++) |
| 1317 | 1287 | { |
| 1318 | | if(mcd212->channel[0].cursor_pattern[y] & (1 << (15 - ((x - curx) >> 1)))) |
| 1288 | if(m_channel[0].cursor_pattern[y] & (1 << (15 - ((x - curx) >> 1)))) |
| 1319 | 1289 | { |
| 1320 | 1290 | scanline[(x++)/2] = color; |
| 1321 | 1291 | scanline[x/2] = color; |
| 1322 | 1292 | } |
| 1323 | | else |
| 1324 | | { |
| 1325 | | } |
| 1326 | 1293 | } |
| 1327 | 1294 | } |
| 1328 | 1295 | } |
| 1329 | 1296 | } |
| 1330 | 1297 | } |
| 1331 | 1298 | |
| 1332 | | static void mcd212_draw_scanline(mcd212_regs_t *mcd212, int y) |
| 1299 | void mcd212_device::draw_scanline(int y) |
| 1333 | 1300 | { |
| 1334 | | bitmap_rgb32 &bitmap = mcd212->m_bitmap; |
| 1335 | 1301 | UINT8 plane_a_r[768], plane_a_g[768], plane_a_b[768]; |
| 1336 | 1302 | UINT8 plane_b_r[768], plane_b_g[768], plane_b_b[768]; |
| 1337 | 1303 | UINT32 out[768]; |
| 1338 | | UINT32 *scanline = &bitmap.pix32(y); |
| 1304 | UINT32 *scanline = &m_bitmap.pix32(y); |
| 1339 | 1305 | int x; |
| 1340 | 1306 | |
| 1341 | | mcd212_process_vsr(mcd212, 0, plane_a_r, plane_a_g, plane_a_b); |
| 1342 | | mcd212_process_vsr(mcd212, 1, plane_b_r, plane_b_g, plane_b_b); |
| 1307 | process_vsr(0, plane_a_r, plane_a_g, plane_a_b); |
| 1308 | process_vsr(1, plane_b_r, plane_b_g, plane_b_b); |
| 1343 | 1309 | |
| 1344 | | mcd212_mix_lines(mcd212, plane_a_r, plane_a_g, plane_a_b, plane_b_r, plane_b_g, plane_b_b, out); |
| 1310 | mix_lines(plane_a_r, plane_a_g, plane_a_b, plane_b_r, plane_b_g, plane_b_b, out); |
| 1345 | 1311 | |
| 1346 | 1312 | for(x = 0; x < 384; x++) |
| 1347 | 1313 | { |
| 1348 | 1314 | scanline[x] = out[x*2]; |
| 1349 | 1315 | } |
| 1350 | 1316 | |
| 1351 | | mcd212_draw_cursor(mcd212, scanline, y); |
| 1317 | draw_cursor(scanline, y); |
| 1352 | 1318 | } |
| 1353 | 1319 | |
| 1354 | | READ16_HANDLER( mcd212_r ) |
| 1320 | READ16_MEMBER( mcd212_device::regs_r ) |
| 1355 | 1321 | { |
| 1356 | | cdi_state *state = space.machine().driver_data<cdi_state>(); |
| 1357 | | mcd212_regs_t *mcd212 = &state->m_mcd212_regs; |
| 1322 | cdi_state *state = machine().driver_data<cdi_state>(); |
| 1358 | 1323 | UINT8 channel = 1 - (offset / 8); |
| 1359 | 1324 | |
| 1360 | 1325 | switch(offset) |
| r20519 | r20520 | |
| 1363 | 1328 | case 0x10/2: |
| 1364 | 1329 | if(ACCESSING_BITS_0_7) |
| 1365 | 1330 | { |
| 1366 | | verboselog(space.machine(), 12, "mcd212_r: Status Register %d: %02x & %04x\n", channel + 1, mcd212->channel[1 - (offset / 8)].csrr, mem_mask); |
| 1331 | verboselog(machine(), 12, "mcd212_r: Status Register %d: %02x & %04x\n", channel + 1, m_channel[1 - (offset / 8)].csrr, mem_mask); |
| 1367 | 1332 | if(channel == 0) |
| 1368 | 1333 | { |
| 1369 | | return mcd212->channel[0].csrr; |
| 1334 | return m_channel[0].csrr; |
| 1370 | 1335 | } |
| 1371 | 1336 | else |
| 1372 | 1337 | { |
| 1373 | | UINT8 old_csr = mcd212->channel[1].csrr; |
| 1338 | UINT8 old_csr = m_channel[1].csrr; |
| 1374 | 1339 | UINT8 interrupt1 = (state->m_scc->get_lir() >> 4) & 7; |
| 1375 | 1340 | //UINT8 interrupt2 = state->m_scc68070_regs.lir & 7; |
| 1376 | | mcd212->channel[1].csrr &= ~(MCD212_CSR2R_IT1 | MCD212_CSR2R_IT2); |
| 1341 | m_channel[1].csrr &= ~(MCD212_CSR2R_IT1 | MCD212_CSR2R_IT2); |
| 1377 | 1342 | if(interrupt1) |
| 1378 | 1343 | { |
| 1379 | 1344 | state->m_maincpu->set_input_line(M68K_IRQ_1 + (interrupt1 - 1), CLEAR_LINE); |
| r20519 | r20520 | |
| 1387 | 1352 | } |
| 1388 | 1353 | else |
| 1389 | 1354 | { |
| 1390 | | verboselog(space.machine(), 2, "mcd212_r: Unknown Register %d: %04x\n", channel + 1, mem_mask); |
| 1355 | verboselog(machine(), 2, "mcd212_r: Unknown Register %d: %04x\n", channel + 1, mem_mask); |
| 1391 | 1356 | } |
| 1392 | 1357 | break; |
| 1393 | 1358 | case 0x02/2: |
| 1394 | 1359 | case 0x12/2: |
| 1395 | | verboselog(space.machine(), 2, "mcd212_r: Display Command Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, mcd212->channel[1 - (offset / 8)].dcr, mem_mask); |
| 1396 | | return mcd212->channel[1 - (offset / 8)].dcr; |
| 1360 | verboselog(machine(), 2, "mcd212_r: Display Command Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, m_channel[1 - (offset / 8)].dcr, mem_mask); |
| 1361 | return m_channel[1 - (offset / 8)].dcr; |
| 1397 | 1362 | case 0x04/2: |
| 1398 | 1363 | case 0x14/2: |
| 1399 | | verboselog(space.machine(), 2, "mcd212_r: Video Start Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, mcd212->channel[1 - (offset / 8)].vsr, mem_mask); |
| 1400 | | return mcd212->channel[1 - (offset / 8)].vsr; |
| 1364 | verboselog(machine(), 2, "mcd212_r: Video Start Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, m_channel[1 - (offset / 8)].vsr, mem_mask); |
| 1365 | return m_channel[1 - (offset / 8)].vsr; |
| 1401 | 1366 | case 0x08/2: |
| 1402 | 1367 | case 0x18/2: |
| 1403 | | verboselog(space.machine(), 2, "mcd212_r: Display Decoder Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, mcd212->channel[1 - (offset / 8)].ddr, mem_mask); |
| 1404 | | return mcd212->channel[1 - (offset / 8)].ddr; |
| 1368 | verboselog(machine(), 2, "mcd212_r: Display Decoder Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, m_channel[1 - (offset / 8)].ddr, mem_mask); |
| 1369 | return m_channel[1 - (offset / 8)].ddr; |
| 1405 | 1370 | case 0x0a/2: |
| 1406 | 1371 | case 0x1a/2: |
| 1407 | | verboselog(space.machine(), 2, "mcd212_r: DCA Pointer Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, mcd212->channel[1 - (offset / 8)].dcp, mem_mask); |
| 1408 | | return mcd212->channel[1 - (offset / 8)].dcp; |
| 1372 | verboselog(machine(), 2, "mcd212_r: DCA Pointer Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, m_channel[1 - (offset / 8)].dcp, mem_mask); |
| 1373 | return m_channel[1 - (offset / 8)].dcp; |
| 1409 | 1374 | default: |
| 1410 | | verboselog(space.machine(), 2, "mcd212_r: Unknown Register %d & %04x\n", (1 - (offset / 8)) + 1, mem_mask); |
| 1375 | verboselog(machine(), 2, "mcd212_r: Unknown Register %d & %04x\n", (1 - (offset / 8)) + 1, mem_mask); |
| 1411 | 1376 | break; |
| 1412 | 1377 | } |
| 1413 | 1378 | |
| 1414 | 1379 | return 0; |
| 1415 | 1380 | } |
| 1416 | 1381 | |
| 1417 | | WRITE16_HANDLER( mcd212_w ) |
| 1382 | WRITE16_MEMBER( mcd212_device::regs_w ) |
| 1418 | 1383 | { |
| 1419 | | cdi_state *state = space.machine().driver_data<cdi_state>(); |
| 1420 | | mcd212_regs_t *mcd212 = &state->m_mcd212_regs; |
| 1421 | | |
| 1422 | 1384 | switch(offset) |
| 1423 | 1385 | { |
| 1424 | 1386 | case 0x00/2: |
| 1425 | 1387 | case 0x10/2: |
| 1426 | | verboselog(space.machine(), 2, "mcd212_w: Status Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); |
| 1427 | | COMBINE_DATA(&mcd212->channel[1 - (offset / 8)].csrw); |
| 1428 | | mcd212_update_visible_area(space.machine()); |
| 1388 | verboselog(machine(), 2, "mcd212_w: Status Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); |
| 1389 | COMBINE_DATA(&m_channel[1 - (offset / 8)].csrw); |
| 1390 | update_visible_area(); |
| 1429 | 1391 | break; |
| 1430 | 1392 | case 0x02/2: |
| 1431 | 1393 | case 0x12/2: |
| 1432 | | verboselog(space.machine(), 2, "mcd212_w: Display Command Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); |
| 1433 | | COMBINE_DATA(&mcd212->channel[1 - (offset / 8)].dcr); |
| 1434 | | mcd212_update_visible_area(space.machine()); |
| 1394 | verboselog(machine(), 2, "mcd212_w: Display Command Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); |
| 1395 | COMBINE_DATA(&m_channel[1 - (offset / 8)].dcr); |
| 1396 | update_visible_area(); |
| 1435 | 1397 | break; |
| 1436 | 1398 | case 0x04/2: |
| 1437 | 1399 | case 0x14/2: |
| 1438 | | verboselog(space.machine(), 2, "mcd212_w: Video Start Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); |
| 1439 | | COMBINE_DATA(&mcd212->channel[1 - (offset / 8)].vsr); |
| 1400 | verboselog(machine(), 2, "mcd212_w: Video Start Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); |
| 1401 | COMBINE_DATA(&m_channel[1 - (offset / 8)].vsr); |
| 1440 | 1402 | break; |
| 1441 | 1403 | case 0x08/2: |
| 1442 | 1404 | case 0x18/2: |
| 1443 | | verboselog(space.machine(), 2, "mcd212_w: Display Decoder Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); |
| 1444 | | COMBINE_DATA(&mcd212->channel[1 - (offset / 8)].ddr); |
| 1405 | verboselog(machine(), 2, "mcd212_w: Display Decoder Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); |
| 1406 | COMBINE_DATA(&m_channel[1 - (offset / 8)].ddr); |
| 1445 | 1407 | break; |
| 1446 | 1408 | case 0x0a/2: |
| 1447 | 1409 | case 0x1a/2: |
| 1448 | | verboselog(space.machine(), 2, "mcd212_w: DCA Pointer Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); |
| 1449 | | COMBINE_DATA(&mcd212->channel[1 - (offset / 8)].dcp); |
| 1410 | verboselog(machine(), 2, "mcd212_w: DCA Pointer Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); |
| 1411 | COMBINE_DATA(&m_channel[1 - (offset / 8)].dcp); |
| 1450 | 1412 | break; |
| 1451 | 1413 | default: |
| 1452 | | verboselog(space.machine(), 2, "mcd212_w: Unknown Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); |
| 1414 | verboselog(machine(), 2, "mcd212_w: Unknown Register %d: %04x & %04x\n", (1 - (offset / 8)) + 1, data, mem_mask); |
| 1453 | 1415 | break; |
| 1454 | 1416 | } |
| 1455 | 1417 | } |
| 1456 | 1418 | |
| 1457 | | TIMER_CALLBACK( mcd212_perform_scan ) |
| 1419 | TIMER_CALLBACK_MEMBER( mcd212_device::perform_scan ) |
| 1458 | 1420 | { |
| 1459 | | cdi_state *state = machine.driver_data<cdi_state>(); |
| 1460 | | mcd212_regs_t *mcd212 = &state->m_mcd212_regs; |
| 1461 | | int scanline = machine.primary_screen->vpos(); |
| 1421 | int scanline = machine().primary_screen->vpos(); |
| 1462 | 1422 | |
| 1463 | | if(/*mcd212->channel[0].dcr & MCD212_DCR_DE*/1) |
| 1423 | if(1) |
| 1464 | 1424 | { |
| 1465 | 1425 | if(scanline == 0) |
| 1466 | 1426 | { |
| 1467 | 1427 | // Process ICA |
| 1468 | | int index = 0; |
| 1469 | 1428 | verboselog(machine, 6, "Frame Start\n" ); |
| 1470 | | mcd212->channel[0].csrr &= 0x7f; |
| 1471 | | for(index = 0; index < 2; index++) |
| 1429 | m_channel[0].csrr &= 0x7f; |
| 1430 | for(int index = 0; index < 2; index++) |
| 1472 | 1431 | { |
| 1473 | | if(mcd212->channel[index].dcr & MCD212_DCR_ICA) |
| 1432 | if(m_channel[index].dcr & MCD212_DCR_ICA) |
| 1474 | 1433 | { |
| 1475 | | mcd212_process_ica(mcd212, index); |
| 1434 | process_ica(index); |
| 1476 | 1435 | } |
| 1477 | 1436 | } |
| 1478 | | cdi220_draw_lcd(machine, scanline); |
| 1437 | draw_lcd(scanline); |
| 1479 | 1438 | } |
| 1480 | 1439 | else if(scanline < 22) |
| 1481 | 1440 | { |
| 1482 | | cdi220_draw_lcd(machine, scanline); |
| 1441 | draw_lcd(scanline); |
| 1483 | 1442 | } |
| 1484 | 1443 | else if(scanline >= 22) |
| 1485 | 1444 | { |
| 1486 | | int index = 0; |
| 1487 | | mcd212->channel[0].csrr |= 0x80; |
| 1445 | m_channel[0].csrr |= 0x80; |
| 1488 | 1446 | // Process VSR |
| 1489 | | mcd212_draw_scanline(mcd212, scanline); |
| 1447 | draw_scanline(scanline); |
| 1490 | 1448 | // Process DCA |
| 1491 | | for(index = 0; index < 2; index++) |
| 1449 | for(int index = 0; index < 2; index++) |
| 1492 | 1450 | { |
| 1493 | | if(mcd212->channel[index].dcr & MCD212_DCR_DCA) |
| 1451 | if(m_channel[index].dcr & MCD212_DCR_DCA) |
| 1494 | 1452 | { |
| 1495 | 1453 | if(scanline == 22) |
| 1496 | 1454 | { |
| 1497 | | mcd212->channel[index].dca = mcd212_get_dcp(mcd212, index); |
| 1455 | m_channel[index].dca = get_dcp(index); |
| 1498 | 1456 | } |
| 1499 | | mcd212_process_dca(mcd212, index); |
| 1457 | process_dca(index); |
| 1500 | 1458 | } |
| 1501 | 1459 | } |
| 1502 | 1460 | if(scanline == 301) |
| 1503 | 1461 | { |
| 1504 | | mcd212->channel[0].csrr ^= 0x20; |
| 1462 | m_channel[0].csrr ^= 0x20; |
| 1505 | 1463 | } |
| 1506 | 1464 | } |
| 1507 | 1465 | } |
| 1508 | | mcd212->scan_timer->adjust(machine.primary_screen->time_until_pos(( scanline + 1 ) % 302, 0)); |
| 1466 | m_scan_timer->adjust(machine().primary_screen->time_until_pos(( scanline + 1 ) % 302, 0)); |
| 1509 | 1467 | } |
| 1510 | 1468 | |
| 1511 | | void mcd212_init(running_machine &machine, mcd212_regs_t *mcd212) |
| 1469 | void mcd212_device::device_reset() |
| 1512 | 1470 | { |
| 1513 | | mcd212->m_machine = &machine; |
| 1514 | | machine.primary_screen->register_screen_bitmap(mcd212->m_bitmap); |
| 1515 | | |
| 1516 | | int index = 0; |
| 1517 | | for(index = 0; index < 2; index++) |
| 1471 | for(int index = 0; index < 2; index++) |
| 1518 | 1472 | { |
| 1519 | | mcd212->channel[index].csrr = 0; |
| 1520 | | mcd212->channel[index].csrw = 0; |
| 1521 | | mcd212->channel[index].dcr = 0; |
| 1522 | | mcd212->channel[index].vsr = 0; |
| 1523 | | mcd212->channel[index].ddr = 0; |
| 1524 | | mcd212->channel[index].dcp = 0; |
| 1525 | | mcd212->channel[index].dca = 0; |
| 1526 | | memset(mcd212->channel[index].clut_r, 0, 256); |
| 1527 | | memset(mcd212->channel[index].clut_g, 0, 256); |
| 1528 | | memset(mcd212->channel[index].clut_b, 0, 256); |
| 1529 | | mcd212->channel[index].image_coding_method = 0; |
| 1530 | | mcd212->channel[index].transparency_control = 0; |
| 1531 | | mcd212->channel[index].plane_order = 0; |
| 1532 | | mcd212->channel[index].clut_bank = 0; |
| 1533 | | mcd212->channel[index].transparent_color_a = 0; |
| 1534 | | mcd212->channel[index].transparent_color_b = 0; |
| 1535 | | mcd212->channel[index].mask_color_a = 0; |
| 1536 | | mcd212->channel[index].mask_color_b = 0; |
| 1537 | | mcd212->channel[index].dyuv_abs_start_a = 0; |
| 1538 | | mcd212->channel[index].dyuv_abs_start_b = 0; |
| 1539 | | mcd212->channel[index].cursor_position = 0; |
| 1540 | | mcd212->channel[index].cursor_control = 0; |
| 1541 | | memset((UINT8*)&mcd212->channel[index].cursor_pattern, 0, 16 * sizeof(UINT32)); |
| 1542 | | memset((UINT8*)&mcd212->channel[index].region_control, 0, 8 * sizeof(UINT32)); |
| 1543 | | mcd212->channel[index].backdrop_color = 0; |
| 1544 | | mcd212->channel[index].mosaic_hold_a = 0; |
| 1545 | | mcd212->channel[index].mosaic_hold_b = 0; |
| 1546 | | memset(mcd212->channel[index].weight_factor_a, 0, 768); |
| 1547 | | memset(mcd212->channel[index].weight_factor_b, 0, 768); |
| 1473 | m_channel[index].csrr = 0; |
| 1474 | m_channel[index].csrw = 0; |
| 1475 | m_channel[index].dcr = 0; |
| 1476 | m_channel[index].vsr = 0; |
| 1477 | m_channel[index].ddr = 0; |
| 1478 | m_channel[index].dcp = 0; |
| 1479 | m_channel[index].dca = 0; |
| 1480 | memset(m_channel[index].clut_r, 0, 256); |
| 1481 | memset(m_channel[index].clut_g, 0, 256); |
| 1482 | memset(m_channel[index].clut_b, 0, 256); |
| 1483 | m_channel[index].image_coding_method = 0; |
| 1484 | m_channel[index].transparency_control = 0; |
| 1485 | m_channel[index].plane_order = 0; |
| 1486 | m_channel[index].clut_bank = 0; |
| 1487 | m_channel[index].transparent_color_a = 0; |
| 1488 | m_channel[index].transparent_color_b = 0; |
| 1489 | m_channel[index].mask_color_a = 0; |
| 1490 | m_channel[index].mask_color_b = 0; |
| 1491 | m_channel[index].dyuv_abs_start_a = 0; |
| 1492 | m_channel[index].dyuv_abs_start_b = 0; |
| 1493 | m_channel[index].cursor_position = 0; |
| 1494 | m_channel[index].cursor_control = 0; |
| 1495 | memset((UINT8*)&m_channel[index].cursor_pattern, 0, 16 * sizeof(UINT32)); |
| 1496 | memset((UINT8*)&m_channel[index].region_control, 0, 8 * sizeof(UINT32)); |
| 1497 | m_channel[index].backdrop_color = 0; |
| 1498 | m_channel[index].mosaic_hold_a = 0; |
| 1499 | m_channel[index].mosaic_hold_b = 0; |
| 1500 | memset(m_channel[index].weight_factor_a, 0, 768); |
| 1501 | memset(m_channel[index].weight_factor_b, 0, 768); |
| 1548 | 1502 | } |
| 1549 | | memset(mcd212->region_flag_0, 0, 768); |
| 1550 | | memset(mcd212->region_flag_1, 0, 768); |
| 1503 | memset(m_region_flag_0, 0, 768); |
| 1504 | memset(m_region_flag_1, 0, 768); |
| 1505 | } |
| 1551 | 1506 | |
| 1552 | | state_save_register_global_array(machine, mcd212->region_flag_0); |
| 1553 | | state_save_register_global_array(machine, mcd212->region_flag_1); |
| 1554 | | state_save_register_global(machine, mcd212->channel[0].csrr); |
| 1555 | | state_save_register_global(machine, mcd212->channel[0].csrw); |
| 1556 | | state_save_register_global(machine, mcd212->channel[0].dcr); |
| 1557 | | state_save_register_global(machine, mcd212->channel[0].vsr); |
| 1558 | | state_save_register_global(machine, mcd212->channel[0].ddr); |
| 1559 | | state_save_register_global(machine, mcd212->channel[0].dcp); |
| 1560 | | state_save_register_global(machine, mcd212->channel[0].dca); |
| 1561 | | state_save_register_global_array(machine, mcd212->channel[0].clut_r); |
| 1562 | | state_save_register_global_array(machine, mcd212->channel[0].clut_g); |
| 1563 | | state_save_register_global_array(machine, mcd212->channel[0].clut_b); |
| 1564 | | state_save_register_global(machine, mcd212->channel[0].image_coding_method); |
| 1565 | | state_save_register_global(machine, mcd212->channel[0].transparency_control); |
| 1566 | | state_save_register_global(machine, mcd212->channel[0].plane_order); |
| 1567 | | state_save_register_global(machine, mcd212->channel[0].clut_bank); |
| 1568 | | state_save_register_global(machine, mcd212->channel[0].transparent_color_a); |
| 1569 | | state_save_register_global(machine, mcd212->channel[0].transparent_color_b); |
| 1570 | | state_save_register_global(machine, mcd212->channel[0].mask_color_a); |
| 1571 | | state_save_register_global(machine, mcd212->channel[0].mask_color_b); |
| 1572 | | state_save_register_global(machine, mcd212->channel[0].dyuv_abs_start_a); |
| 1573 | | state_save_register_global(machine, mcd212->channel[0].dyuv_abs_start_b); |
| 1574 | | state_save_register_global(machine, mcd212->channel[0].cursor_position); |
| 1575 | | state_save_register_global(machine, mcd212->channel[0].cursor_control); |
| 1576 | | state_save_register_global_array(machine, mcd212->channel[0].cursor_pattern); |
| 1577 | | state_save_register_global_array(machine, mcd212->channel[0].region_control); |
| 1578 | | state_save_register_global(machine, mcd212->channel[0].backdrop_color); |
| 1579 | | state_save_register_global(machine, mcd212->channel[0].mosaic_hold_a); |
| 1580 | | state_save_register_global(machine, mcd212->channel[0].mosaic_hold_b); |
| 1581 | | state_save_register_global_array(machine, mcd212->channel[0].weight_factor_a); |
| 1582 | | state_save_register_global_array(machine, mcd212->channel[0].weight_factor_b); |
| 1583 | | state_save_register_global(machine, mcd212->channel[1].csrr); |
| 1584 | | state_save_register_global(machine, mcd212->channel[1].csrw); |
| 1585 | | state_save_register_global(machine, mcd212->channel[1].dcr); |
| 1586 | | state_save_register_global(machine, mcd212->channel[1].vsr); |
| 1587 | | state_save_register_global(machine, mcd212->channel[1].ddr); |
| 1588 | | state_save_register_global(machine, mcd212->channel[1].dcp); |
| 1589 | | state_save_register_global(machine, mcd212->channel[1].dca); |
| 1590 | | state_save_register_global_array(machine, mcd212->channel[1].clut_r); |
| 1591 | | state_save_register_global_array(machine, mcd212->channel[1].clut_g); |
| 1592 | | state_save_register_global_array(machine, mcd212->channel[1].clut_b); |
| 1593 | | state_save_register_global(machine, mcd212->channel[1].image_coding_method); |
| 1594 | | state_save_register_global(machine, mcd212->channel[1].transparency_control); |
| 1595 | | state_save_register_global(machine, mcd212->channel[1].plane_order); |
| 1596 | | state_save_register_global(machine, mcd212->channel[1].clut_bank); |
| 1597 | | state_save_register_global(machine, mcd212->channel[1].transparent_color_a); |
| 1598 | | state_save_register_global(machine, mcd212->channel[1].transparent_color_b); |
| 1599 | | state_save_register_global(machine, mcd212->channel[1].mask_color_a); |
| 1600 | | state_save_register_global(machine, mcd212->channel[1].mask_color_b); |
| 1601 | | state_save_register_global(machine, mcd212->channel[1].dyuv_abs_start_a); |
| 1602 | | state_save_register_global(machine, mcd212->channel[1].dyuv_abs_start_b); |
| 1603 | | state_save_register_global(machine, mcd212->channel[1].cursor_position); |
| 1604 | | state_save_register_global(machine, mcd212->channel[1].cursor_control); |
| 1605 | | state_save_register_global_array(machine, mcd212->channel[1].cursor_pattern); |
| 1606 | | state_save_register_global_array(machine, mcd212->channel[1].region_control); |
| 1607 | | state_save_register_global(machine, mcd212->channel[1].backdrop_color); |
| 1608 | | state_save_register_global(machine, mcd212->channel[1].mosaic_hold_a); |
| 1609 | | state_save_register_global(machine, mcd212->channel[1].mosaic_hold_b); |
| 1610 | | state_save_register_global_array(machine, mcd212->channel[1].weight_factor_a); |
| 1611 | | state_save_register_global_array(machine, mcd212->channel[1].weight_factor_b); |
| 1507 | //------------------------------------------------- |
| 1508 | // mcd212_device - constructor |
| 1509 | //------------------------------------------------- |
| 1510 | |
| 1511 | mcd212_device::mcd212_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 1512 | : device_t(mconfig, MACHINE_MCD212, "MCD212", tag, owner, clock) |
| 1513 | { |
| 1612 | 1514 | } |
| 1613 | 1515 | |
| 1614 | | void mcd212_ab_init(mcd212_ab_t *mcd212_ab) |
| 1516 | //------------------------------------------------- |
| 1517 | // device_start - device-specific startup |
| 1518 | //------------------------------------------------- |
| 1519 | |
| 1520 | void mcd212_device::device_start() |
| 1615 | 1521 | { |
| 1616 | | WORD68K w = 0; |
| 1617 | | SWORD68K sw = 0; |
| 1618 | | WORD68K d = 0; |
| 1522 | machine().primary_screen->register_screen_bitmap(m_bitmap); |
| 1619 | 1523 | |
| 1620 | | //* Delta decoding array. |
| 1621 | | static const BYTE68K mcd212_abDelta[16] = { 0, 1, 4, 9, 16, 27, 44, 79, 128, 177, 212, 229, 240, 247, 252, 255 }; |
| 1524 | m_scan_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mcd212_device::perform_scan), this)); |
| 1525 | m_scan_timer->adjust(machine().primary_screen->time_until_pos(0, 0)); |
| 1622 | 1526 | |
| 1527 | save_item(NAME(m_region_flag_0)); |
| 1528 | save_item(NAME(m_region_flag_1)); |
| 1529 | save_item(NAME(m_channel[0].csrr)); |
| 1530 | save_item(NAME(m_channel[0].csrw)); |
| 1531 | save_item(NAME(m_channel[0].dcr)); |
| 1532 | save_item(NAME(m_channel[0].vsr)); |
| 1533 | save_item(NAME(m_channel[0].ddr)); |
| 1534 | save_item(NAME(m_channel[0].dcp)); |
| 1535 | save_item(NAME(m_channel[0].dca)); |
| 1536 | save_item(NAME(m_channel[0].clut_r)); |
| 1537 | save_item(NAME(m_channel[0].clut_g)); |
| 1538 | save_item(NAME(m_channel[0].clut_b)); |
| 1539 | save_item(NAME(m_channel[0].image_coding_method)); |
| 1540 | save_item(NAME(m_channel[0].transparency_control)); |
| 1541 | save_item(NAME(m_channel[0].plane_order)); |
| 1542 | save_item(NAME(m_channel[0].clut_bank)); |
| 1543 | save_item(NAME(m_channel[0].transparent_color_a)); |
| 1544 | save_item(NAME(m_channel[0].transparent_color_b)); |
| 1545 | save_item(NAME(m_channel[0].mask_color_a)); |
| 1546 | save_item(NAME(m_channel[0].mask_color_b)); |
| 1547 | save_item(NAME(m_channel[0].dyuv_abs_start_a)); |
| 1548 | save_item(NAME(m_channel[0].dyuv_abs_start_b)); |
| 1549 | save_item(NAME(m_channel[0].cursor_position)); |
| 1550 | save_item(NAME(m_channel[0].cursor_control)); |
| 1551 | save_item(NAME(m_channel[0].cursor_pattern)); |
| 1552 | save_item(NAME(m_channel[0].region_control)); |
| 1553 | save_item(NAME(m_channel[0].backdrop_color)); |
| 1554 | save_item(NAME(m_channel[0].mosaic_hold_a)); |
| 1555 | save_item(NAME(m_channel[0].mosaic_hold_b)); |
| 1556 | save_item(NAME(m_channel[0].weight_factor_a)); |
| 1557 | save_item(NAME(m_channel[0].weight_factor_b)); |
| 1558 | save_item(NAME(m_channel[1].csrr)); |
| 1559 | save_item(NAME(m_channel[1].csrw)); |
| 1560 | save_item(NAME(m_channel[1].dcr)); |
| 1561 | save_item(NAME(m_channel[1].vsr)); |
| 1562 | save_item(NAME(m_channel[1].ddr)); |
| 1563 | save_item(NAME(m_channel[1].dcp)); |
| 1564 | save_item(NAME(m_channel[1].dca)); |
| 1565 | save_item(NAME(m_channel[1].clut_r)); |
| 1566 | save_item(NAME(m_channel[1].clut_g)); |
| 1567 | save_item(NAME(m_channel[1].clut_b)); |
| 1568 | save_item(NAME(m_channel[1].image_coding_method)); |
| 1569 | save_item(NAME(m_channel[1].transparency_control)); |
| 1570 | save_item(NAME(m_channel[1].plane_order)); |
| 1571 | save_item(NAME(m_channel[1].clut_bank)); |
| 1572 | save_item(NAME(m_channel[1].transparent_color_a)); |
| 1573 | save_item(NAME(m_channel[1].transparent_color_b)); |
| 1574 | save_item(NAME(m_channel[1].mask_color_a)); |
| 1575 | save_item(NAME(m_channel[1].mask_color_b)); |
| 1576 | save_item(NAME(m_channel[1].dyuv_abs_start_a)); |
| 1577 | save_item(NAME(m_channel[1].dyuv_abs_start_b)); |
| 1578 | save_item(NAME(m_channel[1].cursor_position)); |
| 1579 | save_item(NAME(m_channel[1].cursor_control)); |
| 1580 | save_item(NAME(m_channel[1].cursor_pattern)); |
| 1581 | save_item(NAME(m_channel[1].region_control)); |
| 1582 | save_item(NAME(m_channel[1].backdrop_color)); |
| 1583 | save_item(NAME(m_channel[1].mosaic_hold_a)); |
| 1584 | save_item(NAME(m_channel[1].mosaic_hold_b)); |
| 1585 | save_item(NAME(m_channel[1].weight_factor_a)); |
| 1586 | save_item(NAME(m_channel[1].weight_factor_b)); |
| 1587 | } |
| 1588 | |
| 1589 | void mcd212_device::ab_init() |
| 1590 | { |
| 1591 | // Delta decoding array. |
| 1592 | static const BYTE68K abDelta[16] = { 0, 1, 4, 9, 16, 27, 44, 79, 128, 177, 212, 229, 240, 247, 252, 255 }; |
| 1593 | |
| 1623 | 1594 | // Initialize delta decoding arrays for each unsigned byte value b. |
| 1624 | | for (d = 0; d < BYTE68K_MAX + 1; d++) |
| 1595 | for (WORD68K d = 0; d < BYTE68K_MAX + 1; d++) |
| 1625 | 1596 | { |
| 1626 | | mcd212_ab->deltaY[d] = mcd212_abDelta[d & 15]; |
| 1597 | m_ab.deltaY[d] = abDelta[d & 15]; |
| 1627 | 1598 | } |
| 1628 | 1599 | |
| 1629 | 1600 | // Initialize delta decoding arrays for each unsigned byte value b. |
| 1630 | | for (d = 0; d < (BYTE68K_MAX + 1); d++) |
| 1601 | for (WORD68K d = 0; d < (BYTE68K_MAX + 1); d++) |
| 1631 | 1602 | { |
| 1632 | | mcd212_ab->deltaUV[d] = mcd212_abDelta[d >> 4]; |
| 1603 | m_ab.deltaUV[d] = abDelta[d >> 4]; |
| 1633 | 1604 | } |
| 1634 | 1605 | |
| 1635 | 1606 | // Initialize color limit and clamp arrays. |
| 1636 | | for (w = 0; w < 3 * BYTE68K_MAX; w++) |
| 1607 | for (WORD68K w = 0; w < 3 * BYTE68K_MAX; w++) |
| 1637 | 1608 | { |
| 1638 | | mcd212_ab->limit[w] = (w < BYTE68K_MAX + 16) ? 0 : w <= 16 + 2 * BYTE68K_MAX ? w - BYTE68K_MAX - 16 : BYTE68K_MAX; |
| 1639 | | mcd212_ab->clamp[w] = (w < BYTE68K_MAX + 32) ? 16 : w <= 16 + 2 * BYTE68K_MAX ? w - BYTE68K_MAX - 16 : BYTE68K_MAX; |
| 1609 | m_ab.limit[w] = (w < BYTE68K_MAX + 16) ? 0 : w <= 16 + 2 * BYTE68K_MAX ? w - BYTE68K_MAX - 16 : BYTE68K_MAX; |
| 1610 | m_ab.clamp[w] = (w < BYTE68K_MAX + 32) ? 16 : w <= 16 + 2 * BYTE68K_MAX ? w - BYTE68K_MAX - 16 : BYTE68K_MAX; |
| 1640 | 1611 | } |
| 1641 | 1612 | |
| 1642 | | for (sw = 0; sw < 0x100; sw++) |
| 1613 | for (SWORD68K sw = 0; sw < 0x100; sw++) |
| 1643 | 1614 | { |
| 1644 | | mcd212_ab->matrixUB[sw] = (444 * (sw - 128)) / 256; |
| 1645 | | mcd212_ab->matrixUG[sw] = - (86 * (sw - 128)) / 256; |
| 1646 | | mcd212_ab->matrixVG[sw] = - (179 * (sw - 128)) / 256; |
| 1647 | | mcd212_ab->matrixVR[sw] = (351 * (sw - 128)) / 256; |
| 1615 | m_ab.matrixUB[sw] = (444 * (sw - 128)) / 256; |
| 1616 | m_ab.matrixUG[sw] = - (86 * (sw - 128)) / 256; |
| 1617 | m_ab.matrixVG[sw] = - (179 * (sw - 128)) / 256; |
| 1618 | m_ab.matrixVR[sw] = (351 * (sw - 128)) / 256; |
| 1648 | 1619 | } |
| 1649 | 1620 | } |
| 1650 | 1621 | |
| 1651 | 1622 | void cdi_state::video_start() |
| 1652 | 1623 | { |
| 1653 | | mcd212_ab_init(&m_mcd212_ab); |
| 1654 | | mcd212_init(machine(), &m_mcd212_regs); |
| 1655 | | m_mcd212_regs.scan_timer = machine().scheduler().timer_alloc(FUNC(mcd212_perform_scan)); |
| 1656 | | m_mcd212_regs.scan_timer->adjust(machine().primary_screen->time_until_pos(0, 0)); |
| 1624 | m_mcd212->ab_init(); |
| 1657 | 1625 | |
| 1658 | 1626 | screen_device *screen = downcast<screen_device *>(machine().device("lcd")); |
| 1659 | 1627 | screen->register_screen_bitmap(m_lcdbitmap); |
| r20519 | r20520 | |
| 1661 | 1629 | |
| 1662 | 1630 | UINT32 cdi_state::screen_update_cdimono1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) |
| 1663 | 1631 | { |
| 1664 | | copybitmap(bitmap, m_mcd212_regs.m_bitmap, 0, 0, 0, 0, cliprect); |
| 1632 | copybitmap(bitmap, m_mcd212->get_bitmap(), 0, 0, 0, 0, cliprect); |
| 1665 | 1633 | return 0; |
| 1666 | 1634 | } |
| 1667 | 1635 | |