src/mess/video/vidbrain.c
| r9270 | r9271 | |
| 1 | 1 | /* |
| 2 | 2 | |
| 3 | 3 | TODO: |
| 4 | | |
| 4 | |
| 5 | 5 | - X order |
| 6 | 6 | - freeze (light pen) |
| 7 | 7 | - screen size |
| 8 | 8 | - scanline based update |
| 9 | | - partial updates to allow mid-screen zoom change |
| 10 | 9 | |
| 11 | 10 | */ |
| 12 | 11 | |
| r9270 | r9271 | |
| 66 | 65 | vidbrain_state *state = space->machine->driver_data<vidbrain_state>(); |
| 67 | 66 | |
| 68 | 67 | UINT8 data = 0xff; |
| 68 | int vpos = state->screen->vpos(); |
| 69 | 69 | |
| 70 | if (vpos >= 262) vpos -= 262; |
| 71 | |
| 70 | 72 | switch (offset) |
| 71 | 73 | { |
| 72 | 74 | case REGISTER_X_FREEZE: |
| r9270 | r9271 | |
| 95 | 97 | |
| 96 | 98 | */ |
| 97 | 99 | |
| 98 | | data = (state->field << 7) | (BIT(state->screen->vpos(), 8) << 1) | BIT(state->freeze_y, 8); |
| 100 | data = (state->field << 7) | (BIT(vpos, 8) << 1) | BIT(state->freeze_y, 8); |
| 99 | 101 | if (LOG) logerror("Y-Freeze High %02x\n", data); |
| 100 | 102 | break; |
| 101 | 103 | |
| 102 | 104 | case REGISTER_CURRENT_Y_LOW: |
| 103 | | data = state->screen->vpos() & 0xff; |
| 105 | data = vpos & 0xff; |
| 104 | 106 | if (LOG) logerror("Current-Y Low %02x\n", data); |
| 105 | 107 | break; |
| 106 | 108 | |
| r9270 | r9271 | |
| 126 | 128 | } |
| 127 | 129 | |
| 128 | 130 | /*------------------------------------------------- |
| 131 | do_partial_update - update screen |
| 132 | -------------------------------------------------*/ |
| 133 | |
| 134 | static void do_partial_update(vidbrain_state *state) |
| 135 | { |
| 136 | int vpos = state->screen->vpos(); |
| 137 | |
| 138 | if (LOG) logerror("Partial screen update at scanline %u\n", vpos); |
| 139 | |
| 140 | state->screen->update_partial(vpos); |
| 141 | } |
| 142 | |
| 143 | /*------------------------------------------------- |
| 129 | 144 | vidbrain_vlsi_w - video VLSI write |
| 130 | 145 | -------------------------------------------------*/ |
| 131 | 146 | |
| 147 | #define IS_CHANGED(_bit) \ |
| 148 | ((state->cmd & _bit) != (data & _bit)) |
| 149 | |
| 132 | 150 | WRITE8_HANDLER( vidbrain_vlsi_w ) |
| 133 | 151 | { |
| 134 | 152 | vidbrain_state *state = space->machine->driver_data<vidbrain_state>(); |
| r9270 | r9271 | |
| 163 | 181 | |
| 164 | 182 | if (LOG) logerror("Final Modifier %02x\n", data); |
| 165 | 183 | |
| 184 | do_partial_update(state); |
| 166 | 185 | state->fmod = data & 0x1f; |
| 167 | 186 | break; |
| 168 | 187 | |
| r9270 | r9271 | |
| 184 | 203 | |
| 185 | 204 | if (LOG) logerror("Background %02x\n", data); |
| 186 | 205 | |
| 206 | do_partial_update(state); |
| 187 | 207 | state->bg = data & 0x1f; |
| 188 | 208 | break; |
| 189 | 209 | |
| r9270 | r9271 | |
| 205 | 225 | |
| 206 | 226 | if (LOG) logerror("Command %02x\n", data); |
| 207 | 227 | |
| 208 | | if (BIT(state->cmd, 7) != BIT(data, 7)) |
| 228 | if (IS_CHANGED(COMMAND_YINT_H_O)) |
| 209 | 229 | { |
| 210 | 230 | set_y_interrupt(state); |
| 211 | 231 | } |
| 212 | 232 | |
| 233 | if (IS_CHANGED(COMMAND_A_B) || IS_CHANGED(COMMAND_Y_ZM) || IS_CHANGED(COMMAND_X_ZM)) |
| 234 | { |
| 235 | do_partial_update(state); |
| 236 | } |
| 237 | |
| 213 | 238 | state->cmd = data; |
| 214 | 239 | break; |
| 215 | 240 | |
| r9270 | r9271 | |
| 276 | 301 | VIDEO_UPDATE( vidbrain ) |
| 277 | 302 | -------------------------------------------------*/ |
| 278 | 303 | |
| 279 | | #define RAM(_offset) state->vlsi_ram[_offset + i] |
| 304 | #define RAM(_offset) \ |
| 305 | state->vlsi_ram[_offset + i] |
| 280 | 306 | |
| 307 | #define IS_VISIBLE(_y) \ |
| 308 | ((_y >= cliprect->min_y) && (_y <= cliprect->max_y)) |
| 309 | |
| 310 | #define DRAW_PIXEL(_scanline, _dot) \ |
| 311 | if (IS_VISIBLE(_scanline)) *BITMAP_ADDR16(bitmap, (_scanline), _dot) = pixel; |
| 312 | |
| 281 | 313 | static VIDEO_UPDATE( vidbrain ) |
| 282 | 314 | { |
| 283 | 315 | vidbrain_state *state = screen->machine->driver_data<vidbrain_state>(); |
| r9270 | r9271 | |
| 323 | 355 | |
| 324 | 356 | if (state->cmd & COMMAND_Y_ZM) |
| 325 | 357 | { |
| 358 | int scanline = y + (sy * 2); |
| 359 | |
| 326 | 360 | if (state->cmd & COMMAND_X_ZM) |
| 327 | 361 | { |
| 328 | | *BITMAP_ADDR16(bitmap, y + (sy * 2), x + (sx * 8) + (bit * 2)) = pixel; |
| 329 | | *BITMAP_ADDR16(bitmap, y + (sy * 2) + 1, x + (sx * 8) + (bit * 2)) = pixel; |
| 330 | | *BITMAP_ADDR16(bitmap, y + (sy * 2), x + (sx * 8) + (bit * 2) + 1) = pixel; |
| 331 | | *BITMAP_ADDR16(bitmap, y + (sy * 2) + 1, x + (sx * 8) + (bit * 2) + 1) = pixel; |
| 362 | int dot = (x * 2) + (sx * 16) + (bit * 2); |
| 363 | |
| 364 | DRAW_PIXEL(scanline, dot); |
| 365 | DRAW_PIXEL(scanline, dot + 1); |
| 366 | DRAW_PIXEL(scanline + 1, dot); |
| 367 | DRAW_PIXEL(scanline + 1, dot + 1); |
| 332 | 368 | } |
| 333 | 369 | else |
| 334 | 370 | { |
| 335 | | *BITMAP_ADDR16(bitmap, y + (sy * 2), x + (sx * 8) + bit) = pixel; |
| 336 | | *BITMAP_ADDR16(bitmap, y + (sy * 2) + 1, x + (sx * 8) + bit) = pixel; |
| 371 | int dot = x + (sx * 8) + bit; |
| 372 | |
| 373 | DRAW_PIXEL(scanline, dot); |
| 374 | DRAW_PIXEL(scanline + 1, dot); |
| 337 | 375 | } |
| 338 | 376 | } |
| 339 | 377 | else |
| 340 | 378 | { |
| 379 | int scanline = y + sy; |
| 380 | |
| 341 | 381 | if (state->cmd & COMMAND_X_ZM) |
| 342 | 382 | { |
| 343 | | *BITMAP_ADDR16(bitmap, y + sy, x + (sx * 8) + (bit * 2)) = pixel; |
| 344 | | *BITMAP_ADDR16(bitmap, y + sy, x + (sx * 8) + (bit * 2) + 1) = pixel; |
| 383 | int dot = (x * 2) + (sx * 16) + (bit * 2); |
| 384 | |
| 385 | DRAW_PIXEL(scanline, dot); |
| 386 | DRAW_PIXEL(scanline, dot + 1); |
| 345 | 387 | } |
| 346 | 388 | else |
| 347 | 389 | { |
| 348 | | *BITMAP_ADDR16(bitmap, y + sy, x + (sx * 8) + bit) = pixel; |
| 390 | int dot = x + (sx * 8) + bit; |
| 391 | |
| 392 | DRAW_PIXEL(scanline, dot); |
| 349 | 393 | } |
| 350 | 394 | } |
| 351 | 395 | |
| r9270 | r9271 | |
| 397 | 441 | |
| 398 | 442 | if ((state->cmd & COMMAND_INT) && !(state->cmd & COMMAND_FRZ)) |
| 399 | 443 | { |
| 444 | if (LOG) logerror("Y-Interrupt at scanline %u\n", state->screen->vpos()); |
| 400 | 445 | // f3853_set_external_interrupt_in_line(state->smi, 1); |
| 401 | 446 | state->ext_int_latch = 1; |
| 402 | 447 | vidbrain_interrupt_check(timer.machine); |
| r9270 | r9271 | |
| 429 | 474 | MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ |
| 430 | 475 | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) |
| 431 | 476 | MDRV_SCREEN_SIZE(320, 525) |
| 432 | | MDRV_SCREEN_VISIBLE_AREA(0, 256-1, 0, 262-1) |
| 477 | MDRV_SCREEN_VISIBLE_AREA(0, 240-1, 0, 240-1) |
| 433 | 478 | MDRV_GFXDECODE(vidbrain) |
| 434 | 479 | MDRV_PALETTE_LENGTH(32) |
| 435 | 480 | MDRV_PALETTE_INIT(vidbrain) |
src/mess/drivers/vidbrain.c
| r9270 | r9271 | |
| 128 | 128 | |
| 129 | 129 | if (!state->sound_clk && sound_clk) |
| 130 | 130 | { |
| 131 | | state->sound_q[0] = BIT(state->keylatch, 0); |
| 132 | | state->sound_q[1] = BIT(state->keylatch, 1); |
| 133 | | |
| 134 | | discrete_sound_w(state->discrete, NODE_01, state->sound_q[0]); |
| 135 | | discrete_sound_w(state->discrete, NODE_02, state->sound_q[1]); |
| 131 | discrete_sound_w(state->discrete, NODE_01, BIT(state->keylatch, 0)); |
| 132 | discrete_sound_w(state->discrete, NODE_02, BIT(state->keylatch, 1)); |
| 136 | 133 | } |
| 137 | 134 | |
| 138 | 135 | state->sound_clk = sound_clk; |
| r9270 | r9271 | |
| 448 | 445 | state_save_register_global(machine, state->keylatch); |
| 449 | 446 | state_save_register_global(machine, state->joy_enable); |
| 450 | 447 | state_save_register_global(machine, state->sound_clk); |
| 451 | | state_save_register_global_array(machine, state->sound_q); |
| 452 | 448 | } |
| 453 | 449 | |
| 454 | 450 | /*************************************************************************** |