trunk/src/mess/includes/odyssey2.h
| r19951 | r19952 | |
| 117 | 117 | DECLARE_WRITE8_MEMBER(lum_write); |
| 118 | 118 | DECLARE_READ8_MEMBER(t1_read); |
| 119 | 119 | DECLARE_DRIVER_INIT(odyssey2); |
| 120 | virtual void machine_start(); |
| 120 | 121 | virtual void machine_reset(); |
| 121 | 122 | virtual void video_start(); |
| 122 | 123 | void video_start_g7400(); |
| r19951 | r19952 | |
| 132 | 133 | ef9341_t m_ef9341; |
| 133 | 134 | UINT8 m_ef934x_ram_a[1024]; |
| 134 | 135 | UINT8 m_ef934x_ram_b[1024]; |
| 136 | UINT8 m_ef934x_ext_char_ram[1024]; |
| 135 | 137 | bool m_g7400; |
| 136 | 138 | |
| 137 | 139 | inline UINT16 ef9340_get_c_addr(); |
| 138 | 140 | inline void ef9340_inc_c(); |
| 141 | // Calculate the external chargen address for a character and slice |
| 142 | inline UINT16 external_chargen_address(UINT8 b, UINT8 slice); |
| 139 | 143 | |
| 140 | 144 | void i824x_scanline(int vpos); |
| 141 | 145 | void er9340_scanline(int vpos); |
trunk/src/mess/video/odyssey2.c
| r19951 | r19952 | |
| 721 | 721 | return ( m_ef9340.Y << 5 ) | m_ef9340.X; |
| 722 | 722 | } |
| 723 | 723 | |
| 724 | |
| 724 | 725 | void odyssey2_state::ef9340_inc_c() |
| 725 | 726 | { |
| 726 | 727 | m_ef9340.X++; |
| 727 | 728 | if ( m_ef9340.X >= 40 ) |
| 728 | 729 | { |
| 729 | 730 | m_ef9340.Y = ( m_ef9340.Y + 1 ) % 24; |
| 731 | m_ef9340.X = 0; |
| 730 | 732 | } |
| 731 | 733 | } |
| 732 | 734 | |
| 735 | |
| 736 | UINT16 odyssey2_state::external_chargen_address(UINT8 b, UINT8 slice) |
| 737 | { |
| 738 | UINT8 cc = b & 0x7f; |
| 739 | |
| 740 | if ( slice & 8 ) |
| 741 | { |
| 742 | // 0 0 CCE4 CCE3 CCE2 CCE1 CCE0 CCE6 CCE5 ADR0 |
| 743 | return ( ( cc << 3 ) & 0xf8 ) | ( ( cc >> 4 ) & 0x06) | ( slice & 0x01 ); |
| 744 | } |
| 745 | // CCE6 CCE5 CCE4 CCE3 CCE2 CCE1 CCE0 ADR2 ADR1 ADR0 |
| 746 | return ( cc << 3 ) | ( slice & 0x07 ); |
| 747 | } |
| 748 | |
| 749 | |
| 733 | 750 | void odyssey2_state::ef9341_w( UINT8 command, UINT8 b, UINT8 data ) |
| 734 | 751 | { |
| 735 | 752 | logerror("ef9341 %s write, t%s, data %02X\n", command ? "command" : "data", b ? "B" : "A", data ); |
| r19951 | r19952 | |
| 776 | 793 | { |
| 777 | 794 | if ( b ) |
| 778 | 795 | { |
| 796 | UINT16 addr = ef9340_get_c_addr() & 0x3ff; |
| 797 | |
| 779 | 798 | m_ef9341.TB = data; |
| 780 | 799 | m_ef9341.busy = 0x80; |
| 781 | 800 | switch ( m_ef9340.M & 0xE0 ) |
| 782 | 801 | { |
| 783 | | case 0x00: /* Write */ |
| 784 | | m_ef934x_ram_b[ ef9340_get_c_addr() & 0x3ff ] = m_ef9341.TB; |
| 785 | | ef9340_inc_c(); |
| 786 | | break; |
| 787 | | case 0x20: /* Read */ |
| 788 | | logerror("ef9341 unimplemented data action %02X\n", m_ef9340.M & 0xE0 ); |
| 789 | | ef9340_inc_c(); |
| 790 | | break; |
| 791 | | case 0x40: /* Write without increment */ |
| 792 | | case 0x60: /* Read without increment */ |
| 793 | | case 0x80: /* Write slice */ |
| 794 | | case 0xA0: /* Read slice */ |
| 795 | | logerror("ef9341 unimplemented data action %02X\n", m_ef9340.M & 0xE0 ); |
| 796 | | break; |
| 802 | case 0x00: /* Write */ |
| 803 | m_ef934x_ram_a[addr] = m_ef9341.TA; |
| 804 | m_ef934x_ram_b[addr] = m_ef9341.TB; |
| 805 | ef9340_inc_c(); |
| 806 | break; |
| 807 | |
| 808 | case 0x20: /* Read */ |
| 809 | m_ef9341.TA = m_ef934x_ram_a[addr]; |
| 810 | m_ef9341.TB = m_ef934x_ram_b[addr]; |
| 811 | ef9340_inc_c(); |
| 812 | break; |
| 813 | |
| 814 | case 0x40: /* Write without increment */ |
| 815 | m_ef934x_ram_a[addr] = m_ef9341.TA; |
| 816 | m_ef934x_ram_b[addr] = m_ef9341.TB; |
| 817 | break; |
| 818 | |
| 819 | case 0x60: /* Read without increment */ |
| 820 | m_ef9341.TA = m_ef934x_ram_a[addr]; |
| 821 | m_ef9341.TB = m_ef934x_ram_b[addr]; |
| 822 | break; |
| 823 | |
| 824 | case 0x80: /* Write slice */ |
| 825 | { |
| 826 | UINT8 b = m_ef934x_ram_b[addr]; |
| 827 | UINT8 slice = ( m_ef9340.M & 0x0f ) % 10; |
| 828 | |
| 829 | if ( b >= 0xa0 ) |
| 830 | { |
| 831 | m_ef934x_ext_char_ram[ external_chargen_address( b, slice ) ] = m_ef9341.TA; |
| 832 | } |
| 833 | |
| 834 | // Increment slice number |
| 835 | m_ef9340.M = ( m_ef9340.M & 0xf0) | ( ( slice + 1 ) % 10 ); |
| 836 | } |
| 837 | break; |
| 838 | |
| 839 | case 0xA0: /* Read slice */ |
| 840 | fatalerror/*logerror*/("ef9341 unimplemented data action %02X\n", m_ef9340.M & 0xE0 ); |
| 841 | break; |
| 797 | 842 | } |
| 798 | 843 | m_ef9341.busy = 0; |
| 799 | 844 | } |
| r19951 | r19952 | |
| 825 | 870 | if ( b ) |
| 826 | 871 | { |
| 827 | 872 | data = m_ef9341.TB; |
| 828 | | m_ef9341.busy = 0x80; |
| 829 | 873 | } |
| 830 | 874 | else |
| 831 | 875 | { |
trunk/src/mess/machine/odyssey2.c
| r19951 | r19952 | |
| 79 | 79 | } |
| 80 | 80 | |
| 81 | 81 | |
| 82 | void odyssey2_state::machine_start() |
| 83 | { |
| 84 | save_item(NAME(m_ef934x_ram_a)); |
| 85 | save_item(NAME(m_ef934x_ram_b)); |
| 86 | save_item(NAME(m_ef9340.X)); |
| 87 | save_item(NAME(m_ef9340.Y)); |
| 88 | save_item(NAME(m_ef9340.Y0)); |
| 89 | save_item(NAME(m_ef9340.R)); |
| 90 | save_item(NAME(m_ef9340.M)); |
| 91 | save_item(NAME(m_ef9341.TA)); |
| 92 | save_item(NAME(m_ef9341.TB)); |
| 93 | save_item(NAME(m_ef9341.busy)); |
| 94 | save_item(NAME(m_ef934x_ext_char_ram)); |
| 95 | } |
| 96 | |
| 97 | |
| 82 | 98 | void odyssey2_state::machine_reset() |
| 83 | 99 | { |
| 84 | 100 | /* jump to "last" bank, will work for all sizes due to being mirrored */ |