trunk/src/mame/drivers/taitotz.c
| r24758 | r24759 | |
| 533 | 533 | VECTOR3 light; |
| 534 | 534 | }; |
| 535 | 535 | |
| 536 | | class taitotz_renderer : public poly_manager<float, taitotz_polydata, 6, 50000> |
| 537 | | { |
| 538 | | public: |
| 539 | | taitotz_renderer(running_machine &machine, int width, int height, UINT32 *texram) |
| 540 | | : poly_manager<float, taitotz_polydata, 6, 50000>(machine) |
| 541 | | { |
| 542 | | m_zbuffer = auto_bitmap_ind32_alloc(machine, width, height); |
| 543 | | m_texture = texram; |
| 536 | class taitotz_renderer; |
| 544 | 537 | |
| 545 | | m_diffuse_intensity = 224; |
| 546 | | m_ambient_intensity = 32; |
| 547 | | m_specular_intensity = 256; |
| 548 | | m_specular_power = 20; |
| 549 | | } |
| 550 | | |
| 551 | | void set_fb(bitmap_rgb32 *fb) { m_fb = fb; } |
| 552 | | void render_displaylist(running_machine &machine, const rectangle &cliprect); |
| 553 | | void draw_object(running_machine &machine, UINT32 address, float scale, UINT8 alpha); |
| 554 | | float line_plane_intersection(const vertex_t *v1, const vertex_t *v2, PLANE cp); |
| 555 | | int clip_polygon(const vertex_t *v, int num_vertices, PLANE cp, vertex_t *vout); |
| 556 | | void setup_viewport(int x, int y, int width, int height, int center_x, int center_y); |
| 557 | | void draw_scanline_noz(INT32 scanline, const extent_t &extent, const taitotz_polydata &extradata, int threadid); |
| 558 | | void draw_scanline(INT32 scanline, const extent_t &extent, const taitotz_polydata &extradata, int threadid); |
| 559 | | |
| 560 | | private: |
| 561 | | enum |
| 562 | | { |
| 563 | | POLY_Z = 0, |
| 564 | | POLY_U = 1, |
| 565 | | POLY_V = 2, |
| 566 | | POLY_NX = 3, |
| 567 | | POLY_NY = 4, |
| 568 | | POLY_NZ = 5, |
| 569 | | }; |
| 570 | | |
| 571 | | //static const float ZBUFFER_MAX = 10000000000.0f; |
| 572 | | |
| 573 | | bitmap_rgb32 *m_fb; |
| 574 | | bitmap_ind32 *m_zbuffer; |
| 575 | | UINT32 *m_texture; |
| 576 | | |
| 577 | | PLANE m_clip_plane[6]; |
| 578 | | float m_matrix[4][3]; |
| 579 | | |
| 580 | | float m_diffuse_intensity; |
| 581 | | float m_ambient_intensity; |
| 582 | | float m_specular_intensity; |
| 583 | | float m_specular_power; |
| 584 | | |
| 585 | | int m_ambient_r; |
| 586 | | int m_ambient_g; |
| 587 | | int m_ambient_b; |
| 588 | | int m_diffuse_r; |
| 589 | | int m_diffuse_g; |
| 590 | | int m_diffuse_b; |
| 591 | | int m_specular_r; |
| 592 | | int m_specular_g; |
| 593 | | int m_specular_b; |
| 594 | | |
| 595 | | float m_vp_center_x; |
| 596 | | float m_vp_center_y; |
| 597 | | float m_vp_focus; |
| 598 | | float m_vp_x; |
| 599 | | float m_vp_y; |
| 600 | | float m_vp_mul; |
| 601 | | |
| 602 | | UINT32 m_reg_100; |
| 603 | | UINT32 m_reg_101; |
| 604 | | UINT32 m_reg_102; |
| 605 | | |
| 606 | | UINT32 m_reg_10000100; |
| 607 | | UINT32 m_reg_10000101; |
| 608 | | }; |
| 609 | | |
| 610 | | |
| 611 | | |
| 612 | 538 | class taitotz_state : public driver_device |
| 613 | 539 | { |
| 614 | 540 | public: |
| r24758 | r24759 | |
| 701 | 627 | void init_taitotz_111a(); |
| 702 | 628 | }; |
| 703 | 629 | |
| 630 | class taitotz_renderer : public poly_manager<float, taitotz_polydata, 6, 50000> |
| 631 | { |
| 632 | public: |
| 633 | taitotz_renderer(taitotz_state &state, int width, int height, UINT32 *texram) |
| 634 | : poly_manager<float, taitotz_polydata, 6, 50000>(state.machine()), |
| 635 | m_state(state) |
| 636 | { |
| 637 | m_zbuffer = auto_bitmap_ind32_alloc(state.machine(), width, height); |
| 638 | m_texture = texram; |
| 639 | |
| 640 | m_diffuse_intensity = 224; |
| 641 | m_ambient_intensity = 32; |
| 642 | m_specular_intensity = 256; |
| 643 | m_specular_power = 20; |
| 644 | } |
| 645 | |
| 646 | void set_fb(bitmap_rgb32 *fb) { m_fb = fb; } |
| 647 | void render_displaylist(running_machine &machine, const rectangle &cliprect); |
| 648 | void draw_object(running_machine &machine, UINT32 address, float scale, UINT8 alpha); |
| 649 | float line_plane_intersection(const vertex_t *v1, const vertex_t *v2, PLANE cp); |
| 650 | int clip_polygon(const vertex_t *v, int num_vertices, PLANE cp, vertex_t *vout); |
| 651 | void setup_viewport(int x, int y, int width, int height, int center_x, int center_y); |
| 652 | void draw_scanline_noz(INT32 scanline, const extent_t &extent, const taitotz_polydata &extradata, int threadid); |
| 653 | void draw_scanline(INT32 scanline, const extent_t &extent, const taitotz_polydata &extradata, int threadid); |
| 654 | |
| 655 | private: |
| 656 | enum |
| 657 | { |
| 658 | POLY_Z = 0, |
| 659 | POLY_U = 1, |
| 660 | POLY_V = 2, |
| 661 | POLY_NX = 3, |
| 662 | POLY_NY = 4, |
| 663 | POLY_NZ = 5, |
| 664 | }; |
| 665 | |
| 666 | //static const float ZBUFFER_MAX = 10000000000.0f; |
| 667 | |
| 668 | taitotz_state &m_state; |
| 669 | bitmap_rgb32 *m_fb; |
| 670 | bitmap_ind32 *m_zbuffer; |
| 671 | UINT32 *m_texture; |
| 672 | |
| 673 | PLANE m_clip_plane[6]; |
| 674 | float m_matrix[4][3]; |
| 675 | |
| 676 | float m_diffuse_intensity; |
| 677 | float m_ambient_intensity; |
| 678 | float m_specular_intensity; |
| 679 | float m_specular_power; |
| 680 | |
| 681 | int m_ambient_r; |
| 682 | int m_ambient_g; |
| 683 | int m_ambient_b; |
| 684 | int m_diffuse_r; |
| 685 | int m_diffuse_g; |
| 686 | int m_diffuse_b; |
| 687 | int m_specular_r; |
| 688 | int m_specular_g; |
| 689 | int m_specular_b; |
| 690 | |
| 691 | float m_vp_center_x; |
| 692 | float m_vp_center_y; |
| 693 | float m_vp_focus; |
| 694 | float m_vp_x; |
| 695 | float m_vp_y; |
| 696 | float m_vp_mul; |
| 697 | |
| 698 | UINT32 m_reg_100; |
| 699 | UINT32 m_reg_101; |
| 700 | UINT32 m_reg_102; |
| 701 | |
| 702 | UINT32 m_reg_10000100; |
| 703 | UINT32 m_reg_10000101; |
| 704 | }; |
| 705 | |
| 706 | |
| 707 | |
| 704 | 708 | /* |
| 705 | 709 | void taitotz_state::taitotz_exit() |
| 706 | 710 | { |
| r24758 | r24759 | |
| 751 | 755 | m_texture_ram = auto_alloc_array(machine(), UINT32, 0x800000); |
| 752 | 756 | |
| 753 | 757 | /* create renderer */ |
| 754 | | m_renderer = auto_alloc(machine(), taitotz_renderer(machine(), width, height, m_texture_ram)); |
| 758 | m_renderer = auto_alloc(machine(), taitotz_renderer(*this, width, height, m_texture_ram)); |
| 755 | 759 | |
| 756 | 760 | //machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(taitotz_exit), &machine())); |
| 757 | 761 | } |
| r24758 | r24759 | |
| 1158 | 1162 | |
| 1159 | 1163 | void taitotz_renderer::draw_object(running_machine &machine, UINT32 address, float scale, UINT8 alpha) |
| 1160 | 1164 | { |
| 1161 | | taitotz_state *state = machine.driver_data<taitotz_state>(); |
| 1162 | | const rectangle& visarea = machine.primary_screen->visible_area(); |
| 1165 | const rectangle& visarea = m_state.m_screen->visible_area(); |
| 1163 | 1166 | |
| 1164 | | UINT32 *src = &state->m_screen_ram[address]; |
| 1167 | UINT32 *src = &m_state.m_screen_ram[address]; |
| 1165 | 1168 | taitotz_renderer::vertex_t v[10]; |
| 1166 | 1169 | |
| 1167 | 1170 | |
| r24758 | r24759 | |
| 1343 | 1346 | |
| 1344 | 1347 | void taitotz_renderer::render_displaylist(running_machine &machine, const rectangle &cliprect) |
| 1345 | 1348 | { |
| 1346 | | taitotz_state *state = machine.driver_data<taitotz_state>(); |
| 1347 | | |
| 1348 | 1349 | float zvalue = 0;//ZBUFFER_MAX; |
| 1349 | 1350 | m_zbuffer->fill(*(int*)&zvalue, cliprect); |
| 1350 | 1351 | |
| 1351 | | const rectangle& visarea = machine.primary_screen->visible_area(); |
| 1352 | const rectangle& visarea = m_state.m_screen->visible_area(); |
| 1352 | 1353 | vertex_t v[8]; |
| 1353 | 1354 | |
| 1354 | | UINT32 *src = (UINT32*)&state->m_work_ram[0]; |
| 1355 | UINT32 *src = (UINT32*)&m_state.m_work_ram[0]; |
| 1355 | 1356 | |
| 1356 | 1357 | UINT32 w[32]; |
| 1357 | 1358 | int j; |
| 1358 | 1359 | int end = 0; |
| 1359 | 1360 | |
| 1360 | | UINT32 index = state->m_displist_addr / 4; |
| 1361 | UINT32 index = m_state.m_displist_addr / 4; |
| 1361 | 1362 | |
| 1362 | 1363 | setup_viewport(0, 0, 256, 192, 256, 192); |
| 1363 | 1364 | |
| r24758 | r24759 | |
| 2426 | 2427 | |
| 2427 | 2428 | WRITE8_MEMBER(taitotz_state::tlcs900_port_write) |
| 2428 | 2429 | { |
| 2429 | | //taitotz_state *state = device->machine().driver_data<taitotz_state>(); |
| 2430 | | |
| 2431 | 2430 | switch (offset) |
| 2432 | 2431 | { |
| 2433 | 2432 | case 0x7: |
| r24758 | r24759 | |
| 2438 | 2437 | case 0x8: |
| 2439 | 2438 | if (data & 1) |
| 2440 | 2439 | { |
| 2441 | | //state->m_mbox_ram[0x17] = 0x55; |
| 2440 | //m_mbox_ram[0x17] = 0x55; |
| 2442 | 2441 | } |
| 2443 | 2442 | break; |
| 2444 | 2443 | |
trunk/src/mame/machine/megavdp.c
| r24758 | r24759 | |
| 20 | 20 | int megadrive_vblank_flag = 0; |
| 21 | 21 | |
| 22 | 22 | |
| 23 | | void genesis_vdp_sndirqline_callback_default(running_machine &machine, bool state) |
| 24 | | { |
| 25 | | // if you haven't actually hooked this up.... |
| 26 | | fatalerror("m_genesis_vdp_sndirqline_callback should be connected to something!\n"); |
| 27 | | } |
| 28 | | |
| 29 | | void genesis_vdp_lv6irqline_callback_default(running_machine &machine, bool state) |
| 30 | | { |
| 31 | | // or this... |
| 32 | | fatalerror("m_genesis_vdp_lv6irqline_callback should be connected to something!\n"); |
| 33 | | } |
| 34 | | |
| 35 | | void genesis_vdp_lv4irqline_callback_default(running_machine &machine, bool state) |
| 36 | | { |
| 37 | | // or this... |
| 38 | | fatalerror("m_genesis_vdp_lv4irqline_callback should be connected to something!\n"); |
| 39 | | } |
| 40 | | |
| 41 | 23 | const device_type SEGA_GEN_VDP = &device_creator<sega_genesis_vdp_device>; |
| 42 | 24 | |
| 43 | 25 | sega_genesis_vdp_device::sega_genesis_vdp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 44 | | : sega315_5124_device( mconfig, SEGA315_5246, "Sega Genesis VDP", tag, owner, clock, SEGA315_5124_CRAM_SIZE, 0, true, "sega_genesis_vdp", __FILE__) |
| 26 | : sega315_5124_device( mconfig, SEGA315_5246, "Sega Genesis VDP", tag, owner, clock, SEGA315_5124_CRAM_SIZE, 0, true, "sega_genesis_vdp", __FILE__), |
| 27 | m_genesis_vdp_sndirqline_callback(*this), |
| 28 | m_genesis_vdp_lv6irqline_callback(*this), |
| 29 | m_genesis_vdp_lv4irqline_callback(*this) |
| 45 | 30 | { |
| 46 | | m_genesis_vdp_sndirqline_callback = genesis_vdp_sndirqline_callback_default; |
| 47 | | m_genesis_vdp_lv6irqline_callback = genesis_vdp_lv6irqline_callback_default; |
| 48 | | m_genesis_vdp_lv4irqline_callback = genesis_vdp_lv4irqline_callback_default; |
| 49 | 31 | m_use_alt_timing = 0; |
| 50 | 32 | m_palwrite_base = -1; |
| 51 | 33 | } |
| r24758 | r24759 | |
| 53 | 35 | static TIMER_CALLBACK( megadriv_render_timer_callback ) |
| 54 | 36 | { |
| 55 | 37 | sega_genesis_vdp_device* vdp = (sega_genesis_vdp_device*)ptr; |
| 56 | | vdp->genesis_render_scanline(machine); |
| 38 | vdp->genesis_render_scanline(); |
| 57 | 39 | } |
| 58 | 40 | |
| 59 | | void sega_genesis_vdp_device::vdp_handle_irq6_on_timer_callback(running_machine &machine, int param) |
| 41 | void sega_genesis_vdp_device::vdp_handle_irq6_on_timer_callback(int param) |
| 60 | 42 | { |
| 61 | 43 | // megadrive_irq6_pending = 1; |
| 62 | 44 | if (MEGADRIVE_REG01_IRQ6_ENABLE) |
| 63 | | m_genesis_vdp_lv6irqline_callback(machine, true); |
| 45 | m_genesis_vdp_lv6irqline_callback(true); |
| 64 | 46 | } |
| 65 | 47 | |
| 66 | 48 | static TIMER_CALLBACK( irq6_on_timer_callback ) |
| 67 | 49 | { |
| 68 | 50 | sega_genesis_vdp_device* vdp = (sega_genesis_vdp_device*)ptr; |
| 69 | | vdp->vdp_handle_irq6_on_timer_callback(machine, param); |
| 51 | vdp->vdp_handle_irq6_on_timer_callback(param); |
| 70 | 52 | } |
| 71 | 53 | |
| 72 | | void sega_genesis_vdp_device::vdp_handle_irq4_on_timer_callback(running_machine &machine, int param) |
| 54 | void sega_genesis_vdp_device::vdp_handle_irq4_on_timer_callback(int param) |
| 73 | 55 | { |
| 74 | | m_genesis_vdp_lv4irqline_callback(machine, true); |
| 56 | m_genesis_vdp_lv4irqline_callback(true); |
| 75 | 57 | } |
| 76 | 58 | |
| 77 | 59 | static TIMER_CALLBACK( irq4_on_timer_callback ) |
| 78 | 60 | { |
| 79 | 61 | sega_genesis_vdp_device* vdp = (sega_genesis_vdp_device*)ptr; |
| 80 | | vdp->vdp_handle_irq4_on_timer_callback(machine, param); |
| 62 | vdp->vdp_handle_irq4_on_timer_callback(param); |
| 81 | 63 | } |
| 82 | 64 | |
| 83 | 65 | |
| 84 | 66 | |
| 85 | 67 | |
| 86 | | void sega_genesis_vdp_device::set_genesis_vdp_sndirqline_callback(device_t &device, genesis_vdp_sndirqline_callback_func callback) |
| 87 | | { |
| 88 | | sega_genesis_vdp_device &dev = downcast<sega_genesis_vdp_device &>(device); |
| 89 | | dev.m_genesis_vdp_sndirqline_callback = callback; |
| 90 | | } |
| 91 | | |
| 92 | | void sega_genesis_vdp_device::set_genesis_vdp_lv6irqline_callback(device_t &device, genesis_vdp_lv6irqline_callback_func callback) |
| 93 | | { |
| 94 | | sega_genesis_vdp_device &dev = downcast<sega_genesis_vdp_device &>(device); |
| 95 | | dev.m_genesis_vdp_lv6irqline_callback = callback; |
| 96 | | } |
| 97 | | |
| 98 | | void sega_genesis_vdp_device::set_genesis_vdp_lv4irqline_callback(device_t &device, genesis_vdp_lv4irqline_callback_func callback) |
| 99 | | { |
| 100 | | sega_genesis_vdp_device &dev = downcast<sega_genesis_vdp_device &>(device); |
| 101 | | dev.m_genesis_vdp_lv4irqline_callback = callback; |
| 102 | | } |
| 103 | | |
| 104 | 68 | void sega_genesis_vdp_device::set_genesis_vdp_alt_timing(device_t &device, int use_alt_timing) |
| 105 | 69 | { |
| 106 | 70 | sega_genesis_vdp_device &dev = downcast<sega_genesis_vdp_device &>(device); |
| r24758 | r24759 | |
| 118 | 82 | |
| 119 | 83 | void sega_genesis_vdp_device::device_start() |
| 120 | 84 | { |
| 85 | m_genesis_vdp_sndirqline_callback.resolve_safe(); |
| 86 | m_genesis_vdp_lv6irqline_callback.resolve_safe(); |
| 87 | m_genesis_vdp_lv4irqline_callback.resolve_safe(); |
| 88 | |
| 121 | 89 | m_vram = auto_alloc_array(machine(), UINT16, 0x10000/2); |
| 122 | 90 | m_cram = auto_alloc_array(machine(), UINT16, 0x80/2); |
| 123 | 91 | m_vsram = auto_alloc_array(machine(), UINT16, 0x80/2); |
| r24758 | r24759 | |
| 270 | 238 | m_vdp_address &=0xffff; |
| 271 | 239 | } |
| 272 | 240 | |
| 273 | | void sega_genesis_vdp_device::write_cram_value(running_machine &machine, int offset, int data) |
| 241 | void sega_genesis_vdp_device::write_cram_value(int offset, int data) |
| 274 | 242 | { |
| 275 | 243 | m_cram[offset] = data; |
| 276 | 244 | |
| r24758 | r24759 | |
| 283 | 251 | b = ((data >> 9)&0x07); |
| 284 | 252 | if (m_palwrite_base != -1) |
| 285 | 253 | { |
| 286 | | palette_set_color_rgb(machine,offset + m_palwrite_base ,pal3bit(r),pal3bit(g),pal3bit(b)); |
| 287 | | palette_set_color_rgb(machine,offset + m_palwrite_base + 0x40 ,pal3bit(r>>1),pal3bit(g>>1),pal3bit(b>>1)); |
| 288 | | palette_set_color_rgb(machine,offset + m_palwrite_base + 0x80 ,pal3bit((r>>1)|0x4),pal3bit((g>>1)|0x4),pal3bit((b>>1)|0x4)); |
| 254 | palette_set_color_rgb(machine(),offset + m_palwrite_base ,pal3bit(r),pal3bit(g),pal3bit(b)); |
| 255 | palette_set_color_rgb(machine(),offset + m_palwrite_base + 0x40 ,pal3bit(r>>1),pal3bit(g>>1),pal3bit(b>>1)); |
| 256 | palette_set_color_rgb(machine(),offset + m_palwrite_base + 0x80 ,pal3bit((r>>1)|0x4),pal3bit((g>>1)|0x4),pal3bit((b>>1)|0x4)); |
| 289 | 257 | } |
| 290 | 258 | megadrive_vdp_palette_lookup[offset] = (b<<2) | (g<<7) | (r<<12); |
| 291 | 259 | megadrive_vdp_palette_lookup_sprite[offset] = (b<<2) | (g<<7) | (r<<12); |
| r24758 | r24759 | |
| 294 | 262 | } |
| 295 | 263 | } |
| 296 | 264 | |
| 297 | | void sega_genesis_vdp_device::vdp_cram_write(running_machine &machine, UINT16 data) |
| 265 | void sega_genesis_vdp_device::vdp_cram_write(UINT16 data) |
| 298 | 266 | { |
| 299 | 267 | int offset; |
| 300 | 268 | offset = (m_vdp_address&0x7e)>>1; |
| 301 | 269 | |
| 302 | | write_cram_value(machine, offset,data); |
| 270 | write_cram_value(offset,data); |
| 303 | 271 | |
| 304 | 272 | m_vdp_address+=MEGADRIVE_REG0F_AUTO_INC; |
| 305 | 273 | |
| r24758 | r24759 | |
| 307 | 275 | } |
| 308 | 276 | |
| 309 | 277 | |
| 310 | | void sega_genesis_vdp_device::megadriv_vdp_data_port_w(running_machine &machine, int data) |
| 278 | void sega_genesis_vdp_device::megadriv_vdp_data_port_w(int data) |
| 311 | 279 | { |
| 312 | 280 | m_vdp_command_pending = 0; |
| 313 | 281 | |
| r24758 | r24759 | |
| 375 | 343 | break; |
| 376 | 344 | |
| 377 | 345 | case 0x0003: |
| 378 | | vdp_cram_write(machine, data); |
| 346 | vdp_cram_write(data); |
| 379 | 347 | break; |
| 380 | 348 | |
| 381 | 349 | case 0x0004: |
| r24758 | r24759 | |
| 402 | 370 | |
| 403 | 371 | |
| 404 | 372 | |
| 405 | | void sega_genesis_vdp_device::megadrive_vdp_set_register(running_machine &machine, int regnum, UINT8 value) |
| 373 | void sega_genesis_vdp_device::megadrive_vdp_set_register(int regnum, UINT8 value) |
| 406 | 374 | { |
| 407 | 375 | m_vdp_regs[regnum] = value; |
| 408 | 376 | |
| r24758 | r24759 | |
| 417 | 385 | if (megadrive_irq4_pending) |
| 418 | 386 | { |
| 419 | 387 | if (MEGADRIVE_REG0_IRQ4_ENABLE) |
| 420 | | m_genesis_vdp_lv4irqline_callback(machine, true); |
| 388 | m_genesis_vdp_lv4irqline_callback(true); |
| 421 | 389 | else |
| 422 | | m_genesis_vdp_lv4irqline_callback(machine, false); |
| 390 | m_genesis_vdp_lv4irqline_callback(false); |
| 423 | 391 | } |
| 424 | 392 | |
| 425 | 393 | /* ??? Fatal Rewind needs this but I'm not sure it's accurate behavior |
| r24758 | r24759 | |
| 434 | 402 | if (megadrive_irq6_pending) |
| 435 | 403 | { |
| 436 | 404 | if (MEGADRIVE_REG01_IRQ6_ENABLE ) |
| 437 | | m_genesis_vdp_lv6irqline_callback(machine, true); |
| 405 | m_genesis_vdp_lv6irqline_callback(true); |
| 438 | 406 | else |
| 439 | | m_genesis_vdp_lv6irqline_callback(machine, false); |
| 407 | m_genesis_vdp_lv6irqline_callback(false); |
| 440 | 408 | |
| 441 | 409 | } |
| 442 | 410 | |
| r24758 | r24759 | |
| 448 | 416 | |
| 449 | 417 | |
| 450 | 418 | // if (regnum == 0x0a) |
| 451 | | // mame_printf_debug("Set HINT Reload Register to %d on scanline %d\n",value, genesis_get_scanline_counter(machine)); |
| 419 | // mame_printf_debug("Set HINT Reload Register to %d on scanline %d\n",value, genesis_get_scanline_counter()); |
| 452 | 420 | |
| 453 | | // mame_printf_debug("%s: Setting VDP Register #%02x to %02x\n",machine.describe_context(), regnum,value); |
| 421 | // mame_printf_debug("%s: Setting VDP Register #%02x to %02x\n",machine().describe_context(), regnum,value); |
| 454 | 422 | } |
| 455 | 423 | |
| 456 | 424 | void sega_genesis_vdp_device::update_m_vdp_code_and_address(void) |
| r24758 | r24759 | |
| 538 | 506 | } |
| 539 | 507 | |
| 540 | 508 | /* Instant, but we pause the 68k a bit */ |
| 541 | | void sega_genesis_vdp_device::megadrive_do_insta_68k_to_vram_dma(running_machine &machine, UINT32 source,int length) |
| 509 | void sega_genesis_vdp_device::megadrive_do_insta_68k_to_vram_dma(UINT32 source,int length) |
| 542 | 510 | { |
| 543 | 511 | int count; |
| 544 | 512 | |
| r24758 | r24759 | |
| 549 | 517 | |
| 550 | 518 | for (count = 0;count<(length>>1);count++) |
| 551 | 519 | { |
| 552 | | vdp_vram_write(vdp_get_word_from_68k_mem(machine, source, *m_space68k)); |
| 520 | vdp_vram_write(vdp_get_word_from_68k_mem(machine(), source, *m_space68k)); |
| 553 | 521 | source+=2; |
| 554 | 522 | if (source>0xffffff) source = 0xe00000; |
| 555 | 523 | } |
| r24758 | r24759 | |
| 565 | 533 | } |
| 566 | 534 | |
| 567 | 535 | |
| 568 | | void sega_genesis_vdp_device::megadrive_do_insta_68k_to_cram_dma(running_machine &machine,UINT32 source,UINT16 length) |
| 536 | void sega_genesis_vdp_device::megadrive_do_insta_68k_to_cram_dma(UINT32 source,UINT16 length) |
| 569 | 537 | { |
| 570 | 538 | int count; |
| 571 | 539 | |
| r24758 | r24759 | |
| 575 | 543 | { |
| 576 | 544 | //if (m_vdp_address>=0x80) return; // abandon |
| 577 | 545 | |
| 578 | | write_cram_value(machine, (m_vdp_address&0x7e)>>1, vdp_get_word_from_68k_mem(machine, source, *m_space68k)); |
| 546 | write_cram_value((m_vdp_address&0x7e)>>1, vdp_get_word_from_68k_mem(machine(), source, *m_space68k)); |
| 579 | 547 | source+=2; |
| 580 | 548 | |
| 581 | 549 | if (source>0xffffff) source = 0xfe0000; |
| r24758 | r24759 | |
| 593 | 561 | |
| 594 | 562 | } |
| 595 | 563 | |
| 596 | | void sega_genesis_vdp_device::megadrive_do_insta_68k_to_vsram_dma(running_machine &machine,UINT32 source,UINT16 length) |
| 564 | void sega_genesis_vdp_device::megadrive_do_insta_68k_to_vsram_dma(UINT32 source,UINT16 length) |
| 597 | 565 | { |
| 598 | 566 | int count; |
| 599 | 567 | |
| r24758 | r24759 | |
| 603 | 571 | { |
| 604 | 572 | if (m_vdp_address>=0x80) return; // abandon |
| 605 | 573 | |
| 606 | | m_vsram[(m_vdp_address&0x7e)>>1] = vdp_get_word_from_68k_mem(machine, source, *m_space68k); |
| 574 | m_vsram[(m_vdp_address&0x7e)>>1] = vdp_get_word_from_68k_mem(machine(), source, *m_space68k); |
| 607 | 575 | source+=2; |
| 608 | 576 | |
| 609 | 577 | if (source>0xffffff) source = 0xfe0000; |
| r24758 | r24759 | |
| 621 | 589 | } |
| 622 | 590 | |
| 623 | 591 | /* This can be simplified quite a lot.. */ |
| 624 | | void sega_genesis_vdp_device::handle_dma_bits(running_machine &machine) |
| 592 | void sega_genesis_vdp_device::handle_dma_bits() |
| 625 | 593 | { |
| 626 | 594 | #if 0 |
| 627 | 595 | if (m_vdp_code&0x20) |
| r24758 | r24759 | |
| 630 | 598 | UINT16 length; |
| 631 | 599 | source = (MEGADRIVE_REG15_DMASOURCE1 | (MEGADRIVE_REG16_DMASOURCE2<<8) | ((MEGADRIVE_REG17_DMASOURCE3&0xff)<<16))<<1; |
| 632 | 600 | length = (MEGADRIVE_REG13_DMALENGTH1 | (MEGADRIVE_REG14_DMALENGTH2<<8))<<1; |
| 633 | | mame_printf_debug("%s 68k DMAtran set source %06x length %04x dest %04x enabled %01x code %02x %02x\n", machine.describe_context(), source, length, m_vdp_address,MEGADRIVE_REG01_DMA_ENABLE, m_vdp_code,MEGADRIVE_REG0F_AUTO_INC); |
| 601 | mame_printf_debug("%s 68k DMAtran set source %06x length %04x dest %04x enabled %01x code %02x %02x\n", machine().describe_context(), source, length, m_vdp_address,MEGADRIVE_REG01_DMA_ENABLE, m_vdp_code,MEGADRIVE_REG0F_AUTO_INC); |
| 634 | 602 | } |
| 635 | 603 | #endif |
| 636 | 604 | if (m_vdp_code==0x20) |
| r24758 | r24759 | |
| 648 | 616 | |
| 649 | 617 | /* The 68k is frozen during this transfer, it should be safe to throw a few cycles away and do 'instant' DMA because the 68k can't detect it being in progress (can the z80?) */ |
| 650 | 618 | //mame_printf_debug("68k->VRAM DMA transfer source %06x length %04x dest %04x enabled %01x\n", source, length, m_vdp_address,MEGADRIVE_REG01_DMA_ENABLE); |
| 651 | | if (MEGADRIVE_REG01_DMA_ENABLE) megadrive_do_insta_68k_to_vram_dma(machine,source,length); |
| 619 | if (MEGADRIVE_REG01_DMA_ENABLE) megadrive_do_insta_68k_to_vram_dma(source,length); |
| 652 | 620 | |
| 653 | 621 | } |
| 654 | 622 | else if (MEGADRIVE_REG17_DMATYPE==0x2) |
| r24758 | r24759 | |
| 682 | 650 | |
| 683 | 651 | /* The 68k is frozen during this transfer, it should be safe to throw a few cycles away and do 'instant' DMA because the 68k can't detect it being in progress (can the z80?) */ |
| 684 | 652 | //mame_printf_debug("68k->CRAM DMA transfer source %06x length %04x dest %04x enabled %01x\n", source, length, m_vdp_address,MEGADRIVE_REG01_DMA_ENABLE); |
| 685 | | if (MEGADRIVE_REG01_DMA_ENABLE) megadrive_do_insta_68k_to_cram_dma(machine,source,length); |
| 653 | if (MEGADRIVE_REG01_DMA_ENABLE) megadrive_do_insta_68k_to_cram_dma(source,length); |
| 686 | 654 | } |
| 687 | 655 | else if (MEGADRIVE_REG17_DMATYPE==0x2) |
| 688 | 656 | { |
| r24758 | r24759 | |
| 709 | 677 | |
| 710 | 678 | /* The 68k is frozen during this transfer, it should be safe to throw a few cycles away and do 'instant' DMA because the 68k can't detect it being in progress (can the z80?) */ |
| 711 | 679 | //mame_printf_debug("68k->VSRAM DMA transfer source %06x length %04x dest %04x enabled %01x\n", source, length, m_vdp_address,MEGADRIVE_REG01_DMA_ENABLE); |
| 712 | | if (MEGADRIVE_REG01_DMA_ENABLE) megadrive_do_insta_68k_to_vsram_dma(machine,source,length); |
| 680 | if (MEGADRIVE_REG01_DMA_ENABLE) megadrive_do_insta_68k_to_vsram_dma(source,length); |
| 713 | 681 | } |
| 714 | 682 | else if (MEGADRIVE_REG17_DMATYPE==0x2) |
| 715 | 683 | { |
| r24758 | r24759 | |
| 752 | 720 | } |
| 753 | 721 | } |
| 754 | 722 | |
| 755 | | void sega_genesis_vdp_device::megadriv_vdp_ctrl_port_w(running_machine &machine, int data) |
| 723 | void sega_genesis_vdp_device::megadriv_vdp_ctrl_port_w(int data) |
| 756 | 724 | { |
| 757 | 725 | // logerror("write to vdp control port %04x\n",data); |
| 758 | 726 | m_vram_fill_pending = 0; // ?? |
| r24758 | r24759 | |
| 764 | 732 | m_vdp_command_part2 = data; |
| 765 | 733 | |
| 766 | 734 | update_m_vdp_code_and_address(); |
| 767 | | handle_dma_bits(machine); |
| 735 | handle_dma_bits(); |
| 768 | 736 | |
| 769 | 737 | //logerror("VDP Write Part 2 setting Code %02x Address %04x\n",m_vdp_code, m_vdp_address); |
| 770 | 738 | |
| r24758 | r24759 | |
| 778 | 746 | |
| 779 | 747 | if (regnum &0x20) mame_printf_debug("reg error\n"); |
| 780 | 748 | |
| 781 | | megadrive_vdp_set_register(machine, regnum&0x1f,value); |
| 749 | megadrive_vdp_set_register(regnum&0x1f,value); |
| 782 | 750 | m_vdp_code = 0; |
| 783 | 751 | m_vdp_address = 0; |
| 784 | 752 | } |
| r24758 | r24759 | |
| 809 | 777 | data = (data&0xff00) | data>>8; |
| 810 | 778 | // mame_printf_debug("8-bit write VDP data port access, offset %04x data %04x mem_mask %04x\n",offset,data,mem_mask); |
| 811 | 779 | } |
| 812 | | megadriv_vdp_data_port_w(space.machine(), data); |
| 780 | megadriv_vdp_data_port_w(data); |
| 813 | 781 | break; |
| 814 | 782 | |
| 815 | 783 | case 0x04: |
| 816 | 784 | case 0x06: |
| 817 | 785 | if ((!ACCESSING_BITS_8_15) || (!ACCESSING_BITS_0_7)) mame_printf_debug("8-bit write VDP control port access, offset %04x data %04x mem_mask %04x\n",offset,data,mem_mask); |
| 818 | | megadriv_vdp_ctrl_port_w(space.machine(), data); |
| 786 | megadriv_vdp_ctrl_port_w(data); |
| 819 | 787 | break; |
| 820 | 788 | |
| 821 | 789 | case 0x08: |
| r24758 | r24759 | |
| 831 | 799 | case 0x16: |
| 832 | 800 | { |
| 833 | 801 | // accessed by either segapsg_device or sn76496_device |
| 834 | | sn76496_base_device *sn = space.machine().device<sn76496_base_device>(":snsnd"); |
| 802 | sn76496_base_device *sn = machine().device<sn76496_base_device>(":snsnd"); |
| 835 | 803 | if (ACCESSING_BITS_0_7) sn->write(space, 0, data & 0xff); |
| 836 | 804 | //if (ACCESSING_BITS_8_15) sn->write(space, 0, (data>>8) & 0xff); |
| 837 | 805 | break; |
| r24758 | r24759 | |
| 857 | 825 | return m_cram[(m_vdp_address&0x7e)>>1]; |
| 858 | 826 | } |
| 859 | 827 | |
| 860 | | UINT16 sega_genesis_vdp_device::megadriv_vdp_data_port_r(running_machine &machine) |
| 828 | UINT16 sega_genesis_vdp_device::megadriv_vdp_data_port_r() |
| 861 | 829 | { |
| 862 | 830 | UINT16 retdata=0; |
| 863 | 831 | |
| 864 | | //return machine.rand(); |
| 832 | //return machine().rand(); |
| 865 | 833 | |
| 866 | 834 | m_vdp_command_pending = 0; |
| 867 | 835 | |
| r24758 | r24759 | |
| 875 | 843 | |
| 876 | 844 | case 0x0001: |
| 877 | 845 | logerror("Attempting to READ from DATA PORT in VRAM WRITE MODE\n"); |
| 878 | | retdata = machine.rand(); |
| 846 | retdata = machine().rand(); |
| 879 | 847 | break; |
| 880 | 848 | |
| 881 | 849 | case 0x0003: |
| 882 | 850 | logerror("Attempting to READ from DATA PORT in CRAM WRITE MODE\n"); |
| 883 | | retdata = machine.rand(); |
| 851 | retdata = machine().rand(); |
| 884 | 852 | break; |
| 885 | 853 | |
| 886 | 854 | case 0x0004: |
| r24758 | r24759 | |
| 901 | 869 | |
| 902 | 870 | default: |
| 903 | 871 | logerror("Attempting to READ from DATA PORT in #UNDEFINED# MODE\n"); |
| 904 | | retdata = machine.rand(); |
| 872 | retdata = machine().rand(); |
| 905 | 873 | break; |
| 906 | 874 | } |
| 907 | 875 | |
| r24758 | r24759 | |
| 974 | 942 | |
| 975 | 943 | |
| 976 | 944 | |
| 977 | | UINT16 sega_genesis_vdp_device::megadriv_vdp_ctrl_port_r(running_machine &machine) |
| 945 | UINT16 sega_genesis_vdp_device::megadriv_vdp_ctrl_port_r() |
| 978 | 946 | { |
| 979 | 947 | /* Battletoads is very fussy about the vblank flag |
| 980 | 948 | it wants it to be 1. in scanline 224 */ |
| r24758 | r24759 | |
| 996 | 964 | int fifo_empty = 1; |
| 997 | 965 | int fifo_full = 0; |
| 998 | 966 | |
| 999 | | UINT16 hpos = get_hposition(machine); |
| 967 | UINT16 hpos = get_hposition(); |
| 1000 | 968 | |
| 1001 | 969 | if (hpos>400) megadrive_hblank_flag = 1; |
| 1002 | 970 | if (hpos>460) megadrive_hblank_flag = 0; |
| r24758 | r24759 | |
| 1139 | 1107 | }; |
| 1140 | 1108 | |
| 1141 | 1109 | |
| 1142 | | UINT16 sega_genesis_vdp_device::get_hposition(running_machine &machine) |
| 1110 | UINT16 sega_genesis_vdp_device::get_hposition() |
| 1143 | 1111 | { |
| 1144 | 1112 | UINT16 value4; |
| 1145 | 1113 | |
| r24758 | r24759 | |
| 1161 | 1129 | } |
| 1162 | 1130 | else |
| 1163 | 1131 | { |
| 1164 | | value4 = machine.primary_screen->hpos(); |
| 1132 | value4 = m_screen->hpos(); |
| 1165 | 1133 | } |
| 1166 | 1134 | |
| 1167 | 1135 | return value4; |
| 1168 | 1136 | } |
| 1169 | 1137 | |
| 1170 | | int sega_genesis_vdp_device::genesis_get_scanline_counter(running_machine &machine) |
| 1138 | int sega_genesis_vdp_device::genesis_get_scanline_counter() |
| 1171 | 1139 | { |
| 1172 | 1140 | if (!m_use_alt_timing) |
| 1173 | 1141 | return m_scanline_counter; |
| 1174 | 1142 | else |
| 1175 | | return machine.primary_screen->vpos(); |
| 1143 | return m_screen->vpos(); |
| 1176 | 1144 | } |
| 1177 | 1145 | |
| 1178 | 1146 | |
| 1179 | | UINT16 sega_genesis_vdp_device::megadriv_read_hv_counters(running_machine &machine) |
| 1147 | UINT16 sega_genesis_vdp_device::megadriv_read_hv_counters() |
| 1180 | 1148 | { |
| 1181 | 1149 | /* Bubble and Squeek wants vcount=0xe0 */ |
| 1182 | 1150 | /* Dracula is very sensitive to this */ |
| 1183 | 1151 | /* Marvel Land is sensitive to this */ |
| 1184 | 1152 | |
| 1185 | | int vpos = genesis_get_scanline_counter(machine); |
| 1186 | | UINT16 hpos = get_hposition(machine); |
| 1153 | int vpos = genesis_get_scanline_counter(); |
| 1154 | UINT16 hpos = get_hposition(); |
| 1187 | 1155 | |
| 1188 | 1156 | // if (hpos>424) vpos++; // fixes dracula, breaks road rash |
| 1189 | 1157 | if (hpos>460) vpos++; // when does vpos increase.. also on sms, check game gear manual.. |
| r24758 | r24759 | |
| 1223 | 1191 | case 0x00: |
| 1224 | 1192 | case 0x02: |
| 1225 | 1193 | if ((!ACCESSING_BITS_8_15) || (!ACCESSING_BITS_0_7)) mame_printf_debug("8-bit VDP read data port access, offset %04x mem_mask %04x\n",offset,mem_mask); |
| 1226 | | retvalue = megadriv_vdp_data_port_r(space.machine()); |
| 1194 | retvalue = megadriv_vdp_data_port_r(); |
| 1227 | 1195 | break; |
| 1228 | 1196 | |
| 1229 | 1197 | case 0x04: |
| 1230 | 1198 | case 0x06: |
| 1231 | 1199 | // if ((!ACCESSING_BITS_8_15) || (!ACCESSING_BITS_0_7)) mame_printf_debug("8-bit VDP read control port access, offset %04x mem_mask %04x\n",offset,mem_mask); |
| 1232 | | retvalue = megadriv_vdp_ctrl_port_r(space.machine()); |
| 1233 | | // retvalue = space.machine().rand(); |
| 1234 | | // mame_printf_debug("%06x: Read Control Port at scanline %d hpos %d (return %04x)\n",space.device().safe_pc(),genesis_get_scanline_counter(machine), get_hposition(space.machine()),retvalue); |
| 1200 | retvalue = megadriv_vdp_ctrl_port_r(); |
| 1201 | // retvalue = machine().rand(); |
| 1202 | // mame_printf_debug("%06x: Read Control Port at scanline %d hpos %d (return %04x)\n",space.device().safe_pc(),genesis_get_scanline_counter(), get_hposition(),retvalue); |
| 1235 | 1203 | break; |
| 1236 | 1204 | |
| 1237 | 1205 | case 0x08: |
| r24758 | r24759 | |
| 1239 | 1207 | case 0x0c: |
| 1240 | 1208 | case 0x0e: |
| 1241 | 1209 | // if ((!ACCESSING_BITS_8_15) || (!ACCESSING_BITS_0_7)) mame_printf_debug("8-bit VDP read HV counter port access, offset %04x mem_mask %04x\n",offset,mem_mask); |
| 1242 | | retvalue = megadriv_read_hv_counters(space.machine()); |
| 1243 | | // retvalue = space.machine().rand(); |
| 1244 | | // mame_printf_debug("%06x: Read HV counters at scanline %d hpos %d (return %04x)\n",space.device().safe_pc(),genesis_get_scanline_counter(machine), get_hposition(space.machine()),retvalue); |
| 1210 | retvalue = megadriv_read_hv_counters(); |
| 1211 | // retvalue = machine().rand(); |
| 1212 | // mame_printf_debug("%06x: Read HV counters at scanline %d hpos %d (return %04x)\n",space.device().safe_pc(),genesis_get_scanline_counter(), get_hposition(),retvalue); |
| 1245 | 1213 | break; |
| 1246 | 1214 | |
| 1247 | 1215 | case 0x10: |
| r24758 | r24759 | |
| 1561 | 1529 | |
| 1562 | 1530 | //mame_printf_debug("screenwidth %d\n",screenwidth); |
| 1563 | 1531 | |
| 1564 | | //base_w = Machine->rand()&0xff; |
| 1532 | //base_w = machine().rand()&0xff; |
| 1565 | 1533 | |
| 1566 | 1534 | /* Calculate Exactly where we're going to draw the Window, and if the Window Bug applies */ |
| 1567 | 1535 | window_is_bugged = 0; |
| r24758 | r24759 | |
| 2509 | 2477 | |
| 2510 | 2478 | |
| 2511 | 2479 | /* This converts our render buffer to real screen colours */ |
| 2512 | | void sega_genesis_vdp_device::genesis_render_videobuffer_to_screenbuffer(running_machine &machine, int scanline) |
| 2480 | void sega_genesis_vdp_device::genesis_render_videobuffer_to_screenbuffer(int scanline) |
| 2513 | 2481 | { |
| 2514 | | sega_32x_device *_32xdev = machine.device<sega_32x_device>("sega32x"); // take this out of the VDP eventually |
| 2482 | sega_32x_device *_32xdev = machine().device<sega_32x_device>("sega32x"); // take this out of the VDP eventually |
| 2515 | 2483 | UINT16 *lineptr; |
| 2516 | 2484 | |
| 2517 | 2485 | if (!m_use_alt_timing) |
| r24758 | r24759 | |
| 2591 | 2559 | case 0x1a000: // (sprite)shadow set, highlight set - not possible |
| 2592 | 2560 | case 0x1e000: // (sprite)shadow set, highlight set, normal set, not possible |
| 2593 | 2561 | default: |
| 2594 | | lineptr[x] = m_render_line_raw[x] |= (machine.rand() & 0x3f); |
| 2562 | lineptr[x] = m_render_line_raw[x] |= (machine().rand() & 0x3f); |
| 2595 | 2563 | break; |
| 2596 | 2564 | } |
| 2597 | 2565 | } |
| r24758 | r24759 | |
| 2603 | 2571 | } |
| 2604 | 2572 | } |
| 2605 | 2573 | |
| 2606 | | void sega_genesis_vdp_device::genesis_render_scanline(running_machine &machine) |
| 2574 | void sega_genesis_vdp_device::genesis_render_scanline() |
| 2607 | 2575 | { |
| 2608 | | int scanline = genesis_get_scanline_counter(machine); |
| 2576 | int scanline = genesis_get_scanline_counter(); |
| 2609 | 2577 | |
| 2610 | 2578 | if (scanline >= 0 && scanline < m_visible_scanlines) |
| 2611 | 2579 | { |
| 2612 | 2580 | //if (MEGADRIVE_REG01_DMA_ENABLE==0) mame_printf_debug("off\n"); |
| 2613 | | genesis_render_spriteline_to_spritebuffer(genesis_get_scanline_counter(machine)); |
| 2581 | genesis_render_spriteline_to_spritebuffer(genesis_get_scanline_counter()); |
| 2614 | 2582 | genesis_render_videoline_to_videobuffer(scanline); |
| 2615 | | genesis_render_videobuffer_to_screenbuffer(machine, scanline); |
| 2583 | genesis_render_videobuffer_to_screenbuffer(scanline); |
| 2616 | 2584 | } |
| 2617 | 2585 | } |
| 2618 | 2586 | |
| 2619 | | void sega_genesis_vdp_device::vdp_handle_scanline_callback(running_machine &machine, int scanline) |
| 2587 | void sega_genesis_vdp_device::vdp_handle_scanline_callback(int scanline) |
| 2620 | 2588 | { |
| 2621 | 2589 | /* Compensate for some rounding errors |
| 2622 | 2590 | |
| r24758 | r24759 | |
| 2624 | 2592 | to rounding errors in the timer calculation we're not quite there. Let's assume we are |
| 2625 | 2593 | still in the previous scanline for now. |
| 2626 | 2594 | */ |
| 2627 | | sega_32x_device *_32xdev = machine.device<sega_32x_device>("sega32x"); // take this out of the VDP eventually |
| 2595 | sega_32x_device *_32xdev = machine().device<sega_32x_device>("sega32x"); // take this out of the VDP eventually |
| 2628 | 2596 | |
| 2629 | 2597 | |
| 2630 | | if (genesis_get_scanline_counter(machine) != (megadrive_total_scanlines - 1)) |
| 2598 | if (genesis_get_scanline_counter() != (megadrive_total_scanlines - 1)) |
| 2631 | 2599 | { |
| 2632 | 2600 | if (!m_use_alt_timing) m_scanline_counter++; |
| 2633 | | // mame_printf_debug("scanline %d\n",genesis_get_scanline_counter(machine)); |
| 2601 | // mame_printf_debug("scanline %d\n",genesis_get_scanline_counter()); |
| 2634 | 2602 | megadriv_render_timer->adjust(attotime::from_usec(1)); |
| 2635 | 2603 | |
| 2636 | | if (genesis_get_scanline_counter(machine) == m_irq6_scanline) |
| 2604 | if (genesis_get_scanline_counter() == m_irq6_scanline) |
| 2637 | 2605 | { |
| 2638 | | // mame_printf_debug("x %d",genesis_get_scanline_counter(machine)); |
| 2606 | // mame_printf_debug("x %d",genesis_get_scanline_counter()); |
| 2639 | 2607 | irq6_on_timer->adjust(attotime::from_usec(6)); |
| 2640 | 2608 | megadrive_irq6_pending = 1; |
| 2641 | 2609 | megadrive_vblank_flag = 1; |
| r24758 | r24759 | |
| 2650 | 2618 | if (_32xdev) _32xdev->_32x_check_framebuffer_swap(m_scanline_counter >= m_irq6_scanline); |
| 2651 | 2619 | |
| 2652 | 2620 | |
| 2653 | | // if (genesis_get_scanline_counter(machine)==0) m_irq4counter = MEGADRIVE_REG0A_HINT_VALUE; |
| 2621 | // if (genesis_get_scanline_counter()==0) m_irq4counter = MEGADRIVE_REG0A_HINT_VALUE; |
| 2654 | 2622 | // m_irq4counter = MEGADRIVE_REG0A_HINT_VALUE; |
| 2655 | 2623 | |
| 2656 | | if (genesis_get_scanline_counter(machine)<=224) |
| 2624 | if (genesis_get_scanline_counter()<=224) |
| 2657 | 2625 | { |
| 2658 | 2626 | m_irq4counter--; |
| 2659 | 2627 | |
| r24758 | r24759 | |
| 2667 | 2635 | if (MEGADRIVE_REG0_IRQ4_ENABLE) |
| 2668 | 2636 | { |
| 2669 | 2637 | irq4_on_timer->adjust(attotime::from_usec(1)); |
| 2670 | | //mame_printf_debug("irq4 on scanline %d reload %d\n",genesis_get_scanline_counter(machine),MEGADRIVE_REG0A_HINT_VALUE); |
| 2638 | //mame_printf_debug("irq4 on scanline %d reload %d\n",genesis_get_scanline_counter(),MEGADRIVE_REG0A_HINT_VALUE); |
| 2671 | 2639 | } |
| 2672 | 2640 | } |
| 2673 | 2641 | } |
| r24758 | r24759 | |
| 2677 | 2645 | else m_irq4counter=MEGADRIVE_REG0A_HINT_VALUE; |
| 2678 | 2646 | } |
| 2679 | 2647 | |
| 2680 | | //if (genesis_get_scanline_counter(machine)==0) irq4_on_timer->adjust(attotime::from_usec(2)); |
| 2648 | //if (genesis_get_scanline_counter()==0) irq4_on_timer->adjust(attotime::from_usec(2)); |
| 2681 | 2649 | |
| 2682 | 2650 | |
| 2683 | 2651 | if (_32xdev) _32xdev->_32x_scanline_cb1(m_scanline_counter); |
| 2684 | 2652 | |
| 2685 | 2653 | |
| 2686 | | if (genesis_get_scanline_counter(machine) == m_z80irq_scanline) |
| 2654 | if (genesis_get_scanline_counter() == m_z80irq_scanline) |
| 2687 | 2655 | { |
| 2688 | | m_genesis_vdp_sndirqline_callback(machine, true); |
| 2656 | m_genesis_vdp_sndirqline_callback(true); |
| 2689 | 2657 | } |
| 2690 | | if (genesis_get_scanline_counter(machine) == m_z80irq_scanline + 1) |
| 2658 | if (genesis_get_scanline_counter() == m_z80irq_scanline + 1) |
| 2691 | 2659 | { |
| 2692 | | m_genesis_vdp_sndirqline_callback(machine, false); |
| 2660 | m_genesis_vdp_sndirqline_callback(false); |
| 2693 | 2661 | } |
| 2694 | 2662 | } |
| 2695 | 2663 | else /* pretend we're still on the same scanline to compensate for rounding errors */ |
| r24758 | r24759 | |
| 2702 | 2670 | |
| 2703 | 2671 | |
| 2704 | 2672 | |
| 2705 | | void sega_genesis_vdp_device::vdp_handle_eof(running_machine &machine) |
| 2673 | void sega_genesis_vdp_device::vdp_handle_eof() |
| 2706 | 2674 | { |
| 2707 | | sega_32x_device *_32xdev = machine.device<sega_32x_device>("sega32x"); // take this out of the VDP eventually |
| 2675 | sega_32x_device *_32xdev = machine().device<sega_32x_device>("sega32x"); // take this out of the VDP eventually |
| 2708 | 2676 | |
| 2709 | 2677 | rectangle visarea; |
| 2710 | 2678 | int scr_width = 320; |
| r24758 | r24759 | |
| 2756 | 2724 | |
| 2757 | 2725 | visarea.set(0, scr_width - 1, 0, m_visible_scanlines - 1); |
| 2758 | 2726 | |
| 2759 | | machine.primary_screen->configure(480, megadrive_total_scanlines, visarea, machine.primary_screen->frame_period().attoseconds); |
| 2727 | m_screen->configure(480, megadrive_total_scanlines, visarea, m_screen->frame_period().attoseconds); |
| 2760 | 2728 | |
| 2761 | 2729 | |
| 2762 | 2730 | if(_32xdev) _32xdev->m_32x_hcount_compare_val = -1; |
| r24758 | r24759 | |
| 2771 | 2739 | if (!vdp->m_use_alt_timing) |
| 2772 | 2740 | { |
| 2773 | 2741 | timer.machine().scheduler().synchronize(); |
| 2774 | | vdp->vdp_handle_scanline_callback(timer.machine(), param); |
| 2742 | vdp->vdp_handle_scanline_callback(param); |
| 2775 | 2743 | |
| 2776 | 2744 | megadriv_scanline_timer->adjust(attotime::from_hz(vdp->get_framerate()) / megadrive_total_scanlines); |
| 2777 | 2745 | } |
| 2778 | 2746 | else |
| 2779 | 2747 | { |
| 2780 | | vdp->vdp_handle_scanline_callback(timer.machine(), param); |
| 2748 | vdp->vdp_handle_scanline_callback(param); |
| 2781 | 2749 | } |
| 2782 | 2750 | } |
| 2783 | 2751 | |
| r24758 | r24759 | |
| 2790 | 2758 | if (param==0) |
| 2791 | 2759 | { |
| 2792 | 2760 | //printf("where are we? %d %d\n", m_screen->vpos(), vdp->screen().hpos()); |
| 2793 | | vdp->vdp_handle_eof(timer.machine()); |
| 2761 | vdp->vdp_handle_eof(); |
| 2794 | 2762 | //vdp->vdp_clear_bitmap(); |
| 2795 | 2763 | } |
| 2796 | 2764 | |
| 2797 | 2765 | |
| 2798 | | vdp->vdp_handle_scanline_callback(timer.machine(), param); |
| 2766 | vdp->vdp_handle_scanline_callback(param); |
| 2799 | 2767 | |
| 2800 | 2768 | int vpos = vdp->screen().vpos(); |
| 2801 | 2769 | if (vpos > 0) |
trunk/src/mame/machine/megavdp.h
| r24758 | r24759 | |
| 146 | 146 | #define MEGADRIVE_REG17_UNUSED ((m_vdp_regs[0x17]&0x3f)>>0) |
| 147 | 147 | |
| 148 | 148 | |
| 149 | | typedef void (*genesis_vdp_sndirqline_callback_func)(running_machine &machine, bool state); |
| 150 | | typedef void (*genesis_vdp_lv6irqline_callback_func)(running_machine &machine, bool state); |
| 151 | | typedef void (*genesis_vdp_lv4irqline_callback_func)(running_machine &machine, bool state); |
| 152 | | |
| 153 | 149 | TIMER_DEVICE_CALLBACK( megadriv_scanline_timer_callback_alt_timing ); |
| 154 | 150 | |
| 155 | 151 | UINT16 vdp_get_word_from_68k_mem_default(running_machine &machine, UINT32 source, address_space & space68k); |
| r24758 | r24759 | |
| 160 | 156 | public: |
| 161 | 157 | sega_genesis_vdp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 162 | 158 | |
| 163 | | static void set_genesis_vdp_sndirqline_callback(device_t &device, genesis_vdp_sndirqline_callback_func callback); |
| 164 | | static void set_genesis_vdp_lv6irqline_callback(device_t &device, genesis_vdp_lv6irqline_callback_func callback); |
| 165 | | static void set_genesis_vdp_lv4irqline_callback(device_t &device, genesis_vdp_lv4irqline_callback_func callback); |
| 159 | template<class _Object> static devcb2_base &set_genesis_vdp_sndirqline_callback(device_t &device, _Object object) { return downcast<sega_genesis_vdp_device &>(device).m_genesis_vdp_sndirqline_callback.set_callback(object); } |
| 160 | template<class _Object> static devcb2_base &set_genesis_vdp_lv6irqline_callback(device_t &device, _Object object) { return downcast<sega_genesis_vdp_device &>(device).m_genesis_vdp_lv6irqline_callback.set_callback(object); } |
| 161 | template<class _Object> static devcb2_base &set_genesis_vdp_lv4irqline_callback(device_t &device, _Object object) { return downcast<sega_genesis_vdp_device &>(device).m_genesis_vdp_lv4irqline_callback.set_callback(object); } |
| 166 | 162 | static void set_genesis_vdp_alt_timing(device_t &device, int use_alt_timing); |
| 167 | 163 | static void set_genesis_vdp_palwrite_base(device_t &device, int palwrite_base); |
| 168 | 164 | |
| r24758 | r24759 | |
| 173 | 169 | DECLARE_READ16_MEMBER( megadriv_vdp_r ); |
| 174 | 170 | DECLARE_WRITE16_MEMBER( megadriv_vdp_w ); |
| 175 | 171 | |
| 176 | | int genesis_get_scanline_counter(running_machine &machine); |
| 172 | int genesis_get_scanline_counter(); |
| 177 | 173 | |
| 178 | 174 | |
| 179 | | void genesis_render_scanline(running_machine &machine); |
| 180 | | void vdp_handle_scanline_callback(running_machine &machine, int scanline); |
| 181 | | void vdp_handle_irq6_on_timer_callback(running_machine &machine, int param); |
| 182 | | void vdp_handle_irq4_on_timer_callback(running_machine &machine, int param); |
| 183 | | void vdp_handle_eof(running_machine &machine); |
| 175 | void genesis_render_scanline(); |
| 176 | void vdp_handle_scanline_callback(int scanline); |
| 177 | void vdp_handle_irq6_on_timer_callback(int param); |
| 178 | void vdp_handle_irq4_on_timer_callback(int param); |
| 179 | void vdp_handle_eof(); |
| 184 | 180 | void device_reset_old(); |
| 185 | 181 | void vdp_clear_irq6_pending(void) { megadrive_irq6_pending = 0; }; |
| 186 | 182 | void vdp_clear_irq4_pending(void) { megadrive_irq4_pending = 0; }; |
| r24758 | r24759 | |
| 209 | 205 | virtual void device_reset(); |
| 210 | 206 | |
| 211 | 207 | // called when we hit 240 and 241 (used to control the z80 irq line on genesis, or the main irq on c2) |
| 212 | | genesis_vdp_sndirqline_callback_func m_genesis_vdp_sndirqline_callback; |
| 213 | | genesis_vdp_lv6irqline_callback_func m_genesis_vdp_lv6irqline_callback; |
| 214 | | genesis_vdp_lv6irqline_callback_func m_genesis_vdp_lv4irqline_callback; |
| 208 | devcb2_write_line m_genesis_vdp_sndirqline_callback; |
| 209 | devcb2_write_line m_genesis_vdp_lv6irqline_callback; |
| 210 | devcb2_write_line m_genesis_vdp_lv4irqline_callback; |
| 215 | 211 | |
| 216 | 212 | private: |
| 217 | 213 | |
| r24758 | r24759 | |
| 257 | 253 | emu_timer* irq4_on_timer; |
| 258 | 254 | emu_timer* megadriv_render_timer; |
| 259 | 255 | |
| 260 | | |
| 261 | 256 | UINT16 vdp_vram_r(void); |
| 262 | 257 | UINT16 vdp_vsram_r(void); |
| 263 | 258 | UINT16 vdp_cram_r(void); |
| 264 | 259 | |
| 265 | | void megadrive_do_insta_68k_to_cram_dma(running_machine &machine,UINT32 source,UINT16 length); |
| 266 | | void megadrive_do_insta_68k_to_vsram_dma(running_machine &machine,UINT32 source,UINT16 length); |
| 267 | | void megadrive_do_insta_68k_to_vram_dma(running_machine &machine, UINT32 source,int length); |
| 260 | void megadrive_do_insta_68k_to_cram_dma(UINT32 source,UINT16 length); |
| 261 | void megadrive_do_insta_68k_to_vsram_dma(UINT32 source,UINT16 length); |
| 262 | void megadrive_do_insta_68k_to_vram_dma(UINT32 source,int length); |
| 268 | 263 | void megadrive_do_insta_vram_copy(UINT32 source, UINT16 length); |
| 269 | 264 | |
| 270 | 265 | void vdp_vram_write(UINT16 data); |
| 271 | | void vdp_cram_write(running_machine &machine, UINT16 data); |
| 272 | | void write_cram_value(running_machine &machine, int offset, int data); |
| 266 | void vdp_cram_write(UINT16 data); |
| 267 | void write_cram_value(int offset, int data); |
| 273 | 268 | void vdp_vsram_write(UINT16 data); |
| 274 | 269 | |
| 275 | | void megadrive_vdp_set_register(running_machine &machine, int regnum, UINT8 value); |
| 270 | void megadrive_vdp_set_register(int regnum, UINT8 value); |
| 276 | 271 | |
| 277 | | void handle_dma_bits(running_machine &machine); |
| 272 | void handle_dma_bits(); |
| 278 | 273 | |
| 279 | | UINT16 get_hposition(running_machine &machine); |
| 280 | | UINT16 megadriv_read_hv_counters(running_machine &machine); |
| 274 | UINT16 get_hposition(); |
| 275 | UINT16 megadriv_read_hv_counters(); |
| 281 | 276 | |
| 282 | | UINT16 megadriv_vdp_ctrl_port_r(running_machine &machine); |
| 283 | | UINT16 megadriv_vdp_data_port_r(running_machine &machine); |
| 284 | | void megadriv_vdp_data_port_w(running_machine &machine, int data); |
| 285 | | void megadriv_vdp_ctrl_port_w(running_machine &machine, int data); |
| 277 | UINT16 megadriv_vdp_ctrl_port_r(); |
| 278 | UINT16 megadriv_vdp_data_port_r(); |
| 279 | void megadriv_vdp_data_port_w(int data); |
| 280 | void megadriv_vdp_ctrl_port_w(int data); |
| 286 | 281 | void update_m_vdp_code_and_address(void); |
| 287 | 282 | |
| 288 | 283 | |
| 289 | 284 | void genesis_render_spriteline_to_spritebuffer(int scanline); |
| 290 | 285 | void genesis_render_videoline_to_videobuffer(int scanline); |
| 291 | | void genesis_render_videobuffer_to_screenbuffer(running_machine &machine, int scanline); |
| 286 | void genesis_render_videobuffer_to_screenbuffer(int scanline); |
| 292 | 287 | |
| 293 | 288 | /* variables used during emulation - not saved */ |
| 294 | 289 | UINT8* m_sprite_renderline; |