trunk/src/emu/video/315_5124.c
| r32139 | r32140 | |
| 71 | 71 | #define SPROVR_HPOS 24 |
| 72 | 72 | #define SPRCOL_BASEHPOS 59 |
| 73 | 73 | #define X_SCROLL_HPOS 21 |
| 74 | | #define DISPLAY_DISABLED_HPOS 17 /* fixes 'fantdizzy' (SMS PAL game) flicker */ |
| 74 | #define DISPLAY_DISABLED_HPOS 24 /* not verified, works if above 18 (for 'pstrike2') and below 25 (for 'fantdizzy') */ |
| 75 | #define SPR_PATTERN_HPOS 26 /* not verified, needed for 'backtof3' (SMS PAL game) title screen */ |
| 75 | 76 | #define DISPLAY_CB_HPOS 2 /* fixes 'roadrash' (SMS game) title scrolling, due to line counter reload timing */ |
| 76 | 77 | |
| 77 | 78 | #define DRAW_TIME_GG 94 /* 9 + 2 + 14 + 8 + 13 + 96/2 */ |
| r32139 | r32140 | |
| 156 | 157 | , m_cram_size( SEGA315_5124_CRAM_SIZE ) |
| 157 | 158 | , m_palette_offset( 0 ) |
| 158 | 159 | , m_supports_224_240( false ) |
| 159 | | , m_latched_reg6(0) |
| 160 | 160 | , m_is_pal(false) |
| 161 | 161 | , m_int_cb(*this) |
| 162 | 162 | , m_pause_cb(*this) |
| r32139 | r32140 | |
| 173 | 173 | , m_cram_size( cram_size ) |
| 174 | 174 | , m_palette_offset( palette_offset ) |
| 175 | 175 | , m_supports_224_240( supports_224_240 ) |
| 176 | | , m_latched_reg6(0) |
| 177 | 176 | , m_is_pal(false) |
| 178 | 177 | , m_int_cb(*this) |
| 179 | 178 | , m_pause_cb(*this) |
| r32139 | r32140 | |
| 302 | 301 | with the expected VDP hclock value, if the same range is used (from 0 to width-1). */ |
| 303 | 302 | int hclock = hpos - 1; |
| 304 | 303 | if (hclock < 0) |
| 305 | | hclock += m_screen->width(); |
| 304 | hclock += SEGA315_5124_WIDTH; |
| 306 | 305 | |
| 307 | 306 | /* Calculate and store the new hcount. */ |
| 308 | 307 | m_hcounter = ((hclock - active_scr_start) >> 1) & 0xff; |
| r32139 | r32140 | |
| 376 | 375 | m_int_cb(ASSERT_LINE); |
| 377 | 376 | } |
| 378 | 377 | } |
| 379 | | m_latched_reg6 = m_reg[0x06]; |
| 380 | 378 | break; |
| 381 | 379 | |
| 382 | 380 | case TIMER_VINT: |
| r32139 | r32140 | |
| 407 | 405 | + m_frame_timing[TOP_BORDER] + m_frame_timing[ACTIVE_DISPLAY_V] |
| 408 | 406 | + m_frame_timing[BOTTOM_BORDER] + m_frame_timing[BOTTOM_BLANKING]; |
| 409 | 407 | |
| 408 | /* copy current values in case they are not changed until latch time */ |
| 410 | 409 | m_display_disabled = !(m_reg[0x01] & 0x40); |
| 410 | m_reg6copy = m_reg[0x06]; |
| 411 | m_reg8copy = m_reg[0x08]; |
| 411 | 412 | |
| 412 | 413 | vpos_limit -= m_frame_timing[BOTTOM_BLANKING]; |
| 413 | 414 | |
| r32139 | r32140 | |
| 467 | 468 | { |
| 468 | 469 | m_reg9copy = m_reg[0x09]; |
| 469 | 470 | } |
| 470 | | m_reg8copy = m_reg[0x08]; |
| 471 | 471 | |
| 472 | 472 | if (m_line_counter == 0x00) |
| 473 | 473 | { |
| 474 | 474 | m_line_counter = m_reg[0x0a]; |
| 475 | m_hint_timer->adjust( m_screen->time_until_pos( vpos, HINT_HPOS ) ); |
| 475 | 476 | m_pending_status |= STATUS_HINT; |
| 476 | 477 | } |
| 477 | 478 | else |
| 478 | 479 | { |
| 479 | 480 | m_line_counter--; |
| 480 | 481 | } |
| 481 | | m_hint_timer->adjust( m_screen->time_until_pos( vpos, HINT_HPOS ) ); |
| 482 | 482 | |
| 483 | 483 | /* Draw borders */ |
| 484 | 484 | m_lborder_timer->adjust( m_screen->time_until_pos( vpos, SEGA315_5124_LBORDER_START ), vpos ); |
| r32139 | r32140 | |
| 562 | 562 | remaining time, what could also occur due to the ahead time of the timeslice. */ |
| 563 | 563 | if (m_pending_flags_timer->remaining() == attotime::zero) |
| 564 | 564 | { |
| 565 | | hpos = m_screen->width() - 1; |
| 565 | hpos = SEGA315_5124_WIDTH - 1; |
| 566 | 566 | } |
| 567 | 567 | else |
| 568 | 568 | { |
| r32139 | r32140 | |
| 649 | 649 | |
| 650 | 650 | WRITE8_MEMBER( sega315_5124_device::register_write ) |
| 651 | 651 | { |
| 652 | | int reg_num, hpos; |
| 652 | int reg_num; |
| 653 | 653 | |
| 654 | 654 | if (m_pending_reg_write == 0) |
| 655 | 655 | { |
| r32139 | r32140 | |
| 677 | 677 | reg_num = data & 0x0f; |
| 678 | 678 | m_reg[reg_num] = m_addr & 0xff; |
| 679 | 679 | //logerror("%s: %s: setting register %x to %02x\n", machine().describe_context(), tag(), reg_num, m_addr & 0xf ); |
| 680 | | if ( reg_num == 0 && ( m_addr & 0x02 ) ) |
| 681 | | logerror("overscan enabled.\n"); |
| 682 | | |
| 683 | | if (reg_num == 0 || reg_num == 1) |
| 680 | |
| 681 | switch (reg_num) |
| 682 | { |
| 683 | case 0: |
| 684 | 684 | set_display_settings(); |
| 685 | if (m_addr & 0x02) |
| 686 | logerror("overscan enabled.\n"); |
| 687 | break; |
| 688 | case 1: |
| 689 | set_display_settings(); |
| 690 | if (m_screen->hpos() <= DISPLAY_DISABLED_HPOS) |
| 691 | m_display_disabled = !(m_reg[0x01] & 0x40); |
| 692 | break; |
| 693 | case 6: |
| 694 | if (m_screen->hpos() <= SPR_PATTERN_HPOS) |
| 695 | m_reg6copy = m_reg[0x06]; |
| 696 | break; |
| 697 | case 8: |
| 698 | if (m_screen->hpos() <= X_SCROLL_HPOS) |
| 699 | m_reg8copy = m_reg[0x08]; |
| 700 | } |
| 685 | 701 | |
| 686 | | hpos = m_screen->hpos(); |
| 687 | | |
| 688 | | if (reg_num == 1 && hpos <= DISPLAY_DISABLED_HPOS) |
| 689 | | m_display_disabled = !(m_reg[0x01] & 0x40); |
| 690 | | |
| 691 | | if (reg_num == 8 && hpos <= X_SCROLL_HPOS) |
| 692 | | m_reg8copy = m_reg[0x08]; |
| 693 | | |
| 694 | 702 | check_pending_flags(); |
| 695 | 703 | |
| 696 | 704 | if ( ( reg_num == 0 && (m_status & STATUS_HINT) ) || |
| r32139 | r32140 | |
| 966 | 974 | void sega315_5124_device::draw_sprites_mode4( int *line_buffer, int *priority_selected, int line ) |
| 967 | 975 | { |
| 968 | 976 | bool sprite_col_occurred = false; |
| 969 | | int sprite_col_x = m_screen->width(); |
| 977 | int sprite_col_x = SEGA315_5124_WIDTH; |
| 970 | 978 | |
| 971 | | if (m_display_disabled) |
| 979 | if (m_display_disabled || m_sprite_count == 0) |
| 972 | 980 | return; |
| 973 | 981 | |
| 974 | 982 | memset(m_collision_buffer, 0, SEGA315_5124_WIDTH); |
| r32139 | r32140 | |
| 991 | 999 | sprite_x -= 0x08; /* sprite shift */ |
| 992 | 1000 | } |
| 993 | 1001 | |
| 994 | | if (m_latched_reg6 & 0x04) |
| 1002 | if (m_reg6copy & 0x04) |
| 995 | 1003 | { |
| 996 | 1004 | sprite_tile_selected += 256; /* pattern table select */ |
| 997 | 1005 | } |
| r32139 | r32140 | |
| 1122 | 1130 | void sega315_5124_device::draw_sprites_tms9918_mode( int *line_buffer, int line ) |
| 1123 | 1131 | { |
| 1124 | 1132 | bool sprite_col_occurred = false; |
| 1125 | | int sprite_col_x = m_screen->width(); |
| 1126 | | const UINT16 sprite_pattern_base = ((m_latched_reg6 & 0x07) << 11); |
| 1133 | int sprite_col_x = SEGA315_5124_WIDTH; |
| 1134 | UINT16 sprite_pattern_base; |
| 1127 | 1135 | |
| 1128 | | if (m_display_disabled) |
| 1136 | if (m_display_disabled || m_sprite_count == 0) |
| 1129 | 1137 | return; |
| 1130 | 1138 | |
| 1139 | sprite_pattern_base = ((m_reg6copy & 0x07) << 11); |
| 1131 | 1140 | memset(m_collision_buffer, 0, SEGA315_5124_WIDTH); |
| 1132 | 1141 | |
| 1133 | 1142 | /* Draw sprite layer */ |
| r32139 | r32140 | |
| 1401 | 1410 | int *blitline_buffer = m_line_buffer; |
| 1402 | 1411 | int priority_selected[256]; |
| 1403 | 1412 | |
| 1413 | /* Sprite processing is restricted because collisions on top border of extended |
| 1414 | resolution break the scoreboard of Fantasy Dizzy (SMS) on smspal driver */ |
| 1415 | |
| 1404 | 1416 | if ( line < m_frame_timing[ACTIVE_DISPLAY_V] ) |
| 1405 | 1417 | { |
| 1406 | 1418 | switch( m_vdp_mode ) |
| r32139 | r32140 | |
| 1809 | 1821 | m_display_timer = timer_alloc(TIMER_LINE); |
| 1810 | 1822 | m_display_timer->adjust(m_screen->time_until_pos(0, DISPLAY_CB_HPOS), 0, m_screen->scan_period()); |
| 1811 | 1823 | m_pending_flags_timer = timer_alloc(TIMER_FLAGS); |
| 1812 | | m_pending_flags_timer->adjust(m_screen->time_until_pos(0, m_screen->width() - 1), 0, m_screen->scan_period()); |
| 1824 | m_pending_flags_timer->adjust(m_screen->time_until_pos(0, SEGA315_5124_WIDTH - 1), 0, m_screen->scan_period()); |
| 1813 | 1825 | m_draw_timer = timer_alloc(TIMER_DRAW); |
| 1814 | 1826 | m_lborder_timer = timer_alloc(TIMER_LBORDER); |
| 1815 | 1827 | m_rborder_timer = timer_alloc(TIMER_RBORDER); |
| r32139 | r32140 | |
| 1820 | 1832 | save_item(NAME(m_status)); |
| 1821 | 1833 | save_item(NAME(m_pending_status)); |
| 1822 | 1834 | save_item(NAME(m_pending_sprcol_x)); |
| 1835 | save_item(NAME(m_reg6copy)); |
| 1823 | 1836 | save_item(NAME(m_reg8copy)); |
| 1824 | 1837 | save_item(NAME(m_reg9copy)); |
| 1825 | 1838 | save_item(NAME(m_addrmode)); |
| r32139 | r32140 | |
| 1848 | 1861 | save_item(NAME(m_sprite_height)); |
| 1849 | 1862 | save_item(NAME(m_sprite_zoom)); |
| 1850 | 1863 | save_item(NAME(m_CRAM)); |
| 1851 | | save_item(NAME(m_latched_reg6)); |
| 1852 | 1864 | |
| 1853 | 1865 | machine().save().register_postload(save_prepost_delegate(FUNC(sega315_5124_device::vdp_postload), this)); |
| 1854 | 1866 | } |
| r32139 | r32140 | |
| 1869 | 1881 | m_pending_status = 0; |
| 1870 | 1882 | m_pending_sprcol_x = 0; |
| 1871 | 1883 | m_pending_reg_write = 0; |
| 1884 | m_reg6copy = 0; |
| 1872 | 1885 | m_reg8copy = 0; |
| 1873 | 1886 | m_reg9copy = 0; |
| 1874 | 1887 | m_addrmode = 0; |