trunk/src/emu/video/315_5124.c
| r32027 | r32028 | |
| 197 | 197 | |
| 198 | 198 | void sega315_5124_device::set_display_settings() |
| 199 | 199 | { |
| 200 | | bool M1 = m_reg[0x01] & 0x10; |
| 201 | | bool M2 = m_reg[0x00] & 0x02; |
| 202 | | bool M3 = m_reg[0x01] & 0x08; |
| 203 | | bool M4 = m_reg[0x00] & 0x04; |
| 200 | const bool M1 = m_reg[0x01] & 0x10; |
| 201 | const bool M2 = m_reg[0x00] & 0x02; |
| 202 | const bool M3 = m_reg[0x01] & 0x08; |
| 203 | const bool M4 = m_reg[0x00] & 0x04; |
| 204 | 204 | |
| 205 | 205 | m_y_pixels = 192; |
| 206 | 206 | |
| r32027 | r32028 | |
| 274 | 274 | |
| 275 | 275 | READ8_MEMBER( sega315_5124_device::vcount_read ) |
| 276 | 276 | { |
| 277 | const int active_scr_start = m_frame_timing[VERTICAL_BLANKING] + m_frame_timing[TOP_BLANKING] + m_frame_timing[TOP_BORDER]; |
| 277 | 278 | int vpos = m_screen->vpos(); |
| 278 | | int active_scr_start = m_frame_timing[VERTICAL_BLANKING] + m_frame_timing[TOP_BLANKING] + m_frame_timing[TOP_BORDER]; |
| 279 | 279 | |
| 280 | 280 | if (m_screen->hpos() < VCOUNT_CHANGE_HPOS) |
| 281 | 281 | { |
| r32027 | r32028 | |
| 296 | 296 | |
| 297 | 297 | void sega315_5124_device::hcount_latch_at_hpos( int hpos ) |
| 298 | 298 | { |
| 299 | const int active_scr_start = 46; /* 9 + 2 + 14 + 8 + 13 */ |
| 300 | |
| 299 | 301 | /* The emulation core returns a screen hpos that is one position ahead in comparison |
| 300 | 302 | with the expected VDP hclock value, if the same range is used (from 0 to width-1). */ |
| 301 | 303 | int hclock = hpos - 1; |
| r32027 | r32028 | |
| 303 | 305 | hclock += m_screen->width(); |
| 304 | 306 | |
| 305 | 307 | /* Calculate and store the new hcount. */ |
| 306 | | m_hcounter = ((hclock - 46) >> 1) & 0xff; |
| 308 | m_hcounter = ((hclock - active_scr_start) >> 1) & 0xff; |
| 307 | 309 | } |
| 308 | 310 | |
| 309 | 311 | |
| r32027 | r32028 | |
| 323 | 325 | process_line_timer(); |
| 324 | 326 | break; |
| 325 | 327 | |
| 328 | case TIMER_FLAGS: |
| 329 | /* Activate flags that were pending until the end of the line. */ |
| 330 | check_pending_flags(); |
| 331 | break; |
| 332 | |
| 326 | 333 | case TIMER_DRAW: |
| 327 | 334 | update_palette(); |
| 328 | 335 | draw_scanline( SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH, param, m_screen->vpos() - param ); |
| r32027 | r32028 | |
| 395 | 402 | |
| 396 | 403 | void sega315_5124_device::process_line_timer() |
| 397 | 404 | { |
| 398 | | int vpos = m_screen->vpos(); |
| 405 | const int vpos = m_screen->vpos(); |
| 399 | 406 | int vpos_limit = m_frame_timing[VERTICAL_BLANKING] + m_frame_timing[TOP_BLANKING] |
| 400 | 407 | + m_frame_timing[TOP_BORDER] + m_frame_timing[ACTIVE_DISPLAY_V] |
| 401 | 408 | + m_frame_timing[BOTTOM_BORDER] + m_frame_timing[BOTTOM_BLANKING]; |
| 402 | 409 | |
| 403 | 410 | m_display_disabled = !(m_reg[0x01] & 0x40); |
| 404 | 411 | |
| 405 | | /* Activate flags that were pending until the end of previous line. */ |
| 406 | | check_pending_flags(); |
| 407 | | |
| 408 | 412 | vpos_limit -= m_frame_timing[BOTTOM_BLANKING]; |
| 409 | 413 | |
| 410 | 414 | /* Check if we're below the bottom border */ |
| r32027 | r32028 | |
| 550 | 554 | return; |
| 551 | 555 | } |
| 552 | 556 | |
| 553 | | hpos = m_screen->hpos(); |
| 554 | | if (hpos < DISPLAY_CB_HPOS || m_display_timer->remaining() == attotime::zero) |
| 557 | /* A timer ensures that this function will run at least at end of each line. |
| 558 | When this function runs through a CPU instruction executed when the timer |
| 559 | was about to fire, the time added in the CPU timeslice may make hpos() |
| 560 | return some position in the begining of next line. To ensure the instruction |
| 561 | will get updated status, here a maximum hpos is set if the timer reports no |
| 562 | remaining time, what could also occur due to the ahead time of the timeslice. */ |
| 563 | if (m_pending_flags_timer->remaining() == attotime::zero) |
| 555 | 564 | { |
| 556 | | hpos = m_screen->width(); |
| 565 | hpos = m_screen->width() - 1; |
| 557 | 566 | } |
| 567 | else |
| 568 | { |
| 569 | hpos = m_screen->hpos(); |
| 570 | } |
| 558 | 571 | |
| 559 | 572 | if ((m_pending_status & STATUS_HINT) && hpos >= HINT_HPOS) |
| 560 | 573 | { |
| r32027 | r32028 | |
| 785 | 798 | void sega315_5124_device::draw_scanline_mode4( int *line_buffer, int *priority_selected, int line ) |
| 786 | 799 | { |
| 787 | 800 | int tile_column; |
| 788 | | int x_scroll, y_scroll, x_scroll_start_column; |
| 801 | int y_scroll; |
| 789 | 802 | int pixel_x, pixel_plot_x; |
| 790 | 803 | int bit_plane_0, bit_plane_1, bit_plane_2, bit_plane_3; |
| 791 | | int scroll_mod = ( m_y_pixels != 192 ) ? 256 : 224; |
| 792 | | UINT16 name_table_address = get_name_table_address(); |
| 804 | const int scroll_mod = ( m_y_pixels != 192 ) ? 256 : 224; |
| 805 | const UINT16 name_table_address = get_name_table_address(); |
| 793 | 806 | |
| 794 | 807 | /* if top 2 rows of screen not affected by horizontal scrolling, then x_scroll = 0 */ |
| 795 | 808 | /* else x_scroll = m_reg8copy */ |
| 796 | | x_scroll = (((m_reg[0x00] & 0x40) && (line < 16)) ? 0 : 0x0100 - m_reg8copy); |
| 809 | const int x_scroll = (((m_reg[0x00] & 0x40) && (line < 16)) ? 0 : 0x0100 - m_reg8copy); |
| 797 | 810 | |
| 798 | | x_scroll_start_column = (x_scroll >> 3); /* x starting column tile */ |
| 811 | const int x_scroll_start_column = (x_scroll >> 3); /* x starting column tile */ |
| 799 | 812 | |
| 800 | 813 | /* Draw background layer */ |
| 801 | 814 | for (tile_column = 0; tile_column < 33; tile_column++) |
| r32027 | r32028 | |
| 863 | 876 | |
| 864 | 877 | void sega315_5124_device::select_sprites( int line ) |
| 865 | 878 | { |
| 866 | | int sprite_index = 0; |
| 867 | | int max_sprites = 0; |
| 879 | int max_sprites; |
| 868 | 880 | |
| 869 | 881 | m_sprite_count = 0; |
| 870 | | m_sprite_base = ((m_reg[0x05] << 7) & 0x3f00); |
| 871 | 882 | |
| 872 | 883 | if ( m_vdp_mode == 0 || m_vdp_mode == 2 ) |
| 873 | 884 | { |
| r32027 | r32028 | |
| 883 | 894 | if (m_reg[0x01] & 0x01) /* Check if MAG is set */ |
| 884 | 895 | m_sprite_height = m_sprite_height * 2; |
| 885 | 896 | |
| 886 | | for (sprite_index = 0; (sprite_index < 32 * 4) && (m_sprite_count <= max_sprites); sprite_index += 4) |
| 897 | for (int sprite_index = 0; (sprite_index < 32 * 4) && (m_sprite_count <= max_sprites); sprite_index += 4) |
| 887 | 898 | { |
| 888 | 899 | int sprite_y = space().read_byte(m_sprite_base + sprite_index); |
| 889 | 900 | if (sprite_y == 0xd0) |
| r32027 | r32028 | |
| 915 | 926 | m_sprite_height = (m_reg[0x01] & 0x02) ? 16 : 8; |
| 916 | 927 | m_sprite_zoom = (m_reg[0x01] & 0x01) ? 2 : 1; |
| 917 | 928 | |
| 918 | | for (sprite_index = 0; (sprite_index < 64) && (m_sprite_count <= max_sprites); sprite_index++) |
| 929 | for (int sprite_index = 0; (sprite_index < 64) && (m_sprite_count <= max_sprites); sprite_index++) |
| 919 | 930 | { |
| 920 | 931 | int sprite_y = space().read_byte(m_sprite_base + sprite_index); |
| 921 | 932 | if (m_y_pixels == 192 && sprite_y == 0xd0) |
| r32027 | r32028 | |
| 1112 | 1123 | { |
| 1113 | 1124 | bool sprite_col_occurred = false; |
| 1114 | 1125 | int sprite_col_x = m_screen->width(); |
| 1115 | | UINT16 sprite_pattern_base = ((m_latched_reg6 & 0x07) << 11); |
| 1126 | const UINT16 sprite_pattern_base = ((m_latched_reg6 & 0x07) << 11); |
| 1116 | 1127 | |
| 1117 | 1128 | if (m_display_disabled) |
| 1118 | 1129 | return; |
| r32027 | r32028 | |
| 1747 | 1758 | void sega315_5124_device::stop_timers() |
| 1748 | 1759 | { |
| 1749 | 1760 | m_display_timer->adjust(attotime::never); |
| 1761 | m_pending_flags_timer->adjust(attotime::never); |
| 1750 | 1762 | m_hint_timer->adjust(attotime::never); |
| 1751 | 1763 | m_vint_timer->adjust(attotime::never); |
| 1752 | 1764 | m_nmi_timer->adjust(attotime::never); |
| r32027 | r32028 | |
| 1796 | 1808 | |
| 1797 | 1809 | m_display_timer = timer_alloc(TIMER_LINE); |
| 1798 | 1810 | m_display_timer->adjust(m_screen->time_until_pos(0, DISPLAY_CB_HPOS), 0, m_screen->scan_period()); |
| 1811 | 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()); |
| 1799 | 1813 | m_draw_timer = timer_alloc(TIMER_DRAW); |
| 1800 | 1814 | m_lborder_timer = timer_alloc(TIMER_LBORDER); |
| 1801 | 1815 | m_rborder_timer = timer_alloc(TIMER_RBORDER); |