trunk/src/emu/video/315_5124.c
r32684 | r32685 | |
748 | 748 | } |
749 | 749 | |
750 | 750 | |
751 | | UINT16 sega315_5124_device::get_name_table_address() |
| 751 | UINT16 sega315_5124_device::get_name_table_row(int row) |
752 | 752 | { |
753 | | UINT16 result; |
754 | | |
755 | | if ( m_y_pixels != 192 ) |
756 | | { |
757 | | result = ((m_reg[0x02] & 0x0c) << 10) | 0x0700; |
758 | | } |
759 | | else |
760 | | { |
761 | | result = (m_reg[0x02] << 10) & 0x3800; |
762 | | } |
763 | | |
764 | | return result & (((m_reg[0x02] & 0x01) << 10) | 0x3bff); |
| 753 | return ((row >> 3) << 6) & (((m_reg[0x02] & 0x01) << 10) | 0x3bff); |
765 | 754 | } |
766 | 755 | |
767 | 756 | |
768 | | UINT16 sega315_5246_device::get_name_table_address() |
| 757 | UINT16 sega315_5246_device::get_name_table_row(int row) |
769 | 758 | { |
770 | | UINT16 result; |
771 | | |
772 | | if ( m_y_pixels != 192 ) |
773 | | { |
774 | | result = ((m_reg[0x02] & 0x0c) << 10) | 0x0700; |
775 | | } |
776 | | else |
777 | | { |
778 | | result = (m_reg[0x02] << 10) & 0x3800; |
779 | | } |
780 | | |
781 | | return result; |
| 759 | return (row >> 3) << 6; |
782 | 760 | } |
783 | 761 | |
784 | 762 | |
785 | | UINT16 sega315_5378_device::get_name_table_address() |
| 763 | UINT16 sega315_5378_device::get_name_table_row(int row) |
786 | 764 | { |
787 | | UINT16 result; |
788 | | |
789 | | if ( m_y_pixels != 192 ) |
790 | | { |
791 | | result = ((m_reg[0x02] & 0x0c) << 10) | 0x0700; |
792 | | } |
793 | | else |
794 | | { |
795 | | result = (m_reg[0x02] << 10) & 0x3800; |
796 | | } |
797 | | |
798 | | return result; |
| 765 | return (row >> 3) << 6; |
799 | 766 | } |
800 | 767 | |
801 | 768 | |
802 | 769 | void sega315_5124_device::draw_scanline_mode4( int *line_buffer, int *priority_selected, int line ) |
803 | 770 | { |
804 | 771 | int tile_column; |
805 | | int y_scroll; |
| 772 | int y_scroll, scroll_mod; |
806 | 773 | int pixel_x, pixel_plot_x; |
807 | 774 | int bit_plane_0, bit_plane_1, bit_plane_2, bit_plane_3; |
808 | | const int scroll_mod = ( m_y_pixels != 192 ) ? 256 : 224; |
809 | | const UINT16 name_table_address = get_name_table_address(); |
| 775 | UINT16 name_table_address; |
810 | 776 | |
811 | 777 | /* if top 2 rows of screen not affected by horizontal scrolling, then x_scroll = 0 */ |
812 | 778 | /* else x_scroll = m_reg8copy */ |
r32684 | r32685 | |
814 | 780 | |
815 | 781 | const int x_scroll_start_column = (x_scroll >> 3); /* x starting column tile */ |
816 | 782 | |
| 783 | if ( m_y_pixels != 192 ) |
| 784 | { |
| 785 | name_table_address = ((m_reg[0x02] & 0x0c) << 10) | 0x0700; |
| 786 | scroll_mod = 256; |
| 787 | } |
| 788 | else |
| 789 | { |
| 790 | name_table_address = (m_reg[0x02] << 10) & 0x3800; |
| 791 | scroll_mod = 224; |
| 792 | } |
| 793 | |
817 | 794 | /* Draw background layer */ |
818 | 795 | for (tile_column = 0; tile_column < 33; tile_column++) |
819 | 796 | { |
r32684 | r32685 | |
825 | 802 | /* vertical scrolling when bit 7 of reg[0x00] is set */ |
826 | 803 | y_scroll = ((m_reg[0x00] & 0x80) && (tile_column > 23)) ? 0 : m_reg9copy; |
827 | 804 | |
828 | | tile_line = ((tile_column + x_scroll_start_column) & 0x1f) * 2; |
829 | | tile_data = space().read_word(name_table_address + ((((line + y_scroll) % scroll_mod) >> 3) << 6) + tile_line); |
| 805 | tile_line = ((tile_column + x_scroll_start_column) & 0x1f) << 1; |
| 806 | tile_data = space().read_word(name_table_address + get_name_table_row((line + y_scroll) % scroll_mod) + tile_line); |
830 | 807 | |
831 | 808 | tile_selected = (tile_data & 0x01ff); |
832 | 809 | priority_select = tile_data & PRIORITY_BIT; |
r32684 | r32685 | |
891 | 868 | /* Check if MAG is set */ |
892 | 869 | m_sprite_zoom = (m_reg[0x01] & 0x01) ? 2 : 1; |
893 | 870 | |
894 | | if (m_sprite_zoom == 2) |
| 871 | if (m_sprite_zoom > 1) |
895 | 872 | { |
896 | 873 | /* Divide before use the value for comparison, same later with sprite_y, or |
897 | 874 | else an off-by-one bug could occur, as seen with Tarzan, for Game Gear */ |
r32684 | r32685 | |
1041 | 1018 | bool sprite_col_occurred = false; |
1042 | 1019 | int sprite_col_x = SEGA315_5124_WIDTH; |
1043 | 1020 | UINT8 collision_buffer[SEGA315_5124_WIDTH]; |
| 1021 | int plot_min_x = 0; |
1044 | 1022 | |
1045 | 1023 | if (m_display_disabled || m_sprite_count == 0) |
1046 | 1024 | return; |
1047 | 1025 | |
| 1026 | /* Sprites aren't drawn and collisions don't occur on column 0 if it is disabled */ |
| 1027 | if (m_reg[0x00] & 0x20) |
| 1028 | plot_min_x = 8; |
| 1029 | |
1048 | 1030 | memset(collision_buffer, 0, SEGA315_5124_WIDTH); |
1049 | 1031 | |
1050 | 1032 | /* Draw sprite layer */ |
r32684 | r32685 | |
1078 | 1060 | int pixel_plot_x = sprite_x + (pixel_x << 1); |
1079 | 1061 | |
1080 | 1062 | /* check to prevent going outside of active display area */ |
1081 | | if (pixel_plot_x < 0 || pixel_plot_x > 255) |
| 1063 | if (pixel_plot_x < plot_min_x || pixel_plot_x > 255) |
1082 | 1064 | { |
1083 | 1065 | continue; |
1084 | 1066 | } |
r32684 | r32685 | |
1127 | 1109 | int pixel_plot_x = sprite_x + pixel_x; |
1128 | 1110 | |
1129 | 1111 | /* check to prevent going outside of active display area */ |
1130 | | if (pixel_plot_x < 0 || pixel_plot_x > 255) |
| 1112 | if (pixel_plot_x < plot_min_x || pixel_plot_x > 255) |
1131 | 1113 | { |
1132 | 1114 | continue; |
1133 | 1115 | } |
r32684 | r32685 | |
1256 | 1238 | { |
1257 | 1239 | sprite_tile_selected += 2; |
1258 | 1240 | pattern = space().read_byte( sprite_pattern_line + sprite_tile_selected * 8 ); |
1259 | | sprite_x += (m_sprite_zoom == 2 ? 16 : 8); |
| 1241 | sprite_x += (m_sprite_zoom > 1 ? 16 : 8); |
1260 | 1242 | |
1261 | 1243 | for (int pixel_x = 0; pixel_x < 8; pixel_x++) |
1262 | 1244 | { |
trunk/src/emu/video/315_5124.h
r32684 | r32685 | |
88 | 88 | |
89 | 89 | protected: |
90 | 90 | static const int X_SCROLL_HPOS_5124 = 21; |
91 | | static const int X_SCROLL_HPOS_5378 = 35; // Not verified |
| 91 | static const int X_SCROLL_HPOS_5378 = 41; // Not verified, needed for Chicago Syndicate |
92 | 92 | |
93 | 93 | void set_display_settings(); |
94 | 94 | virtual void update_palette(); |
95 | 95 | virtual void cram_write(UINT8 data); |
96 | 96 | virtual void draw_scanline( int pixel_offset_x, int pixel_plot_y, int line ); |
97 | | virtual UINT16 get_name_table_address(); |
| 97 | virtual UINT16 get_name_table_row(int row); |
98 | 98 | void process_line_timer(); |
99 | 99 | void draw_scanline_mode4( int *line_buffer, int *priority_selected, int line ); |
100 | 100 | void draw_sprites_mode4( int *line_buffer, int *priority_selected, int line ); |
r32684 | r32685 | |
190 | 190 | sega315_5246_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
191 | 191 | |
192 | 192 | protected: |
193 | | virtual UINT16 get_name_table_address(); |
| 193 | virtual UINT16 get_name_table_row(int row); |
194 | 194 | }; |
195 | 195 | |
196 | 196 | |
r32684 | r32685 | |
210 | 210 | virtual void update_palette(); |
211 | 211 | virtual void cram_write(UINT8 data); |
212 | 212 | virtual void draw_scanline( int pixel_offset_x, int pixel_plot_y, int line ); |
213 | | virtual UINT16 get_name_table_address(); |
| 213 | virtual UINT16 get_name_table_row(int row); |
214 | 214 | }; |
215 | 215 | |
216 | 216 | |
trunk/src/mess/machine/sms.c
r32684 | r32685 | |
495 | 495 | |
496 | 496 | UINT8 sms_state::read_bus(address_space &space, unsigned int page, UINT16 base_addr, UINT16 offset) |
497 | 497 | { |
498 | | if (m_mem_device_enabled != ENABLE_NONE) |
| 498 | if (m_is_gamegear) |
499 | 499 | { |
| 500 | // Game Gear BIOS behavior, according to Charles MacDonald: "it uses the first |
| 501 | // 1K. The rest of the space is mapped to the cartridge, regardless of the slot |
| 502 | // that's selected. This allows the BIOS to check for the 'TMR SEGA' string at |
| 503 | // 1FF0/3FF0/7FF0, but it can't do a checksum since the first 1K of ROM is |
| 504 | // unavailable. Anyway, once the BIOS decides to run the game, it disables |
| 505 | // itself, and the first 1K is assigned to the cartridge ROM like normal." |
| 506 | |
| 507 | if ((m_mem_device_enabled & ENABLE_BIOS) && page == 3) |
| 508 | return m_BIOS[(m_bios_page[page] * 0x4000) + (offset & 0x3fff)]; |
| 509 | if (m_mem_device_enabled & ENABLE_CART) |
| 510 | return m_cartslot->read_cart(space, base_addr + offset); |
| 511 | } |
| 512 | else if (m_mem_device_enabled != ENABLE_NONE) |
| 513 | { |
500 | 514 | UINT8 data = 0xff; |
501 | 515 | |
502 | 516 | // SMS2 behavior described by Charles MacDonald's SMS notes: |
r32684 | r32685 | |
514 | 528 | |
515 | 529 | return data; |
516 | 530 | } |
517 | | else |
518 | | { |
519 | | return m_region_maincpu->base()[offset]; |
520 | | } |
| 531 | return m_region_maincpu->base()[offset]; |
521 | 532 | } |
522 | 533 | |
523 | 534 | |
r32684 | r32685 | |
583 | 594 | |
584 | 595 | WRITE8_MEMBER(sms_state::gg_sio_w) |
585 | 596 | { |
| 597 | if (m_cartslot->exists() && m_cartslot->m_cart->get_sms_mode()) |
| 598 | return; |
| 599 | |
586 | 600 | logerror("*** write %02X to SIO register #%d\n", data, offset); |
587 | 601 | |
588 | 602 | m_gg_sio[offset & 0x07] = data; |
r32684 | r32685 | |
608 | 622 | |
609 | 623 | READ8_MEMBER(sms_state::gg_sio_r) |
610 | 624 | { |
| 625 | if (m_cartslot->exists() && m_cartslot->m_cart->get_sms_mode()) |
| 626 | return 0xff; |
| 627 | |
611 | 628 | logerror("*** read SIO register #%d\n", offset); |
612 | 629 | |
613 | 630 | switch (offset & 7) |
r32684 | r32685 | |
667 | 684 | logerror("Card ROM port enabled.\n"); |
668 | 685 | } |
669 | 686 | |
670 | | if (!(m_mem_ctrl_reg & IO_CARTRIDGE) && m_cartslot && m_cartslot->exists()) |
| 687 | if ((m_is_gamegear || !(m_mem_ctrl_reg & IO_CARTRIDGE)) && m_cartslot && m_cartslot->exists()) |
671 | 688 | { |
672 | 689 | m_mem_device_enabled |= ENABLE_CART; |
673 | 690 | logerror("Cartridge ROM/RAM enabled.\n"); |