trunk/src/mame/machine/pgmprot_orlegend.c
| r26447 | r26448 | |
| 13 | 13 | #include "emu.h" |
| 14 | 14 | #include "includes/pgm.h" |
| 15 | 15 | |
| 16 | | /*** ASIC 3 (oriental legends protection) ****************************************/ |
| 17 | | |
| 18 | | void pgm_asic3_state::asic3_compute_hold() |
| 16 | void pgm_asic3_state::asic3_compute_hold(int y, int z) |
| 19 | 17 | { |
| 20 | | // The mode is dependent on the region |
| 21 | | static const int modes[4] = { 1, 1, 3, 2 }; |
| 22 | | int mode = modes[ioport("Region")->read() & 3]; |
| 18 | unsigned short old = m_asic3_hold; |
| 23 | 19 | |
| 24 | | switch (mode) |
| 20 | m_asic3_hold = ((old << 1) | (old >> 15)); |
| 21 | |
| 22 | m_asic3_hold ^= 0x2bad; |
| 23 | m_asic3_hold ^= BIT(z, y); |
| 24 | m_asic3_hold ^= BIT(m_asic3_x, 1) << 6; |
| 25 | m_asic3_hold ^= BIT(m_asic3_x, 2) << 10; |
| 26 | m_asic3_hold ^= BIT(old, 5); |
| 27 | |
| 28 | switch (ioport("Region")->read()) // The mode is dependent on the region |
| 25 | 29 | { |
| 26 | | case 1: |
| 27 | | m_asic3_hold = |
| 28 | | (m_asic3_hold << 1) |
| 29 | | ^ 0x2bad |
| 30 | | ^ BIT(m_asic3_hold, 15) ^ BIT(m_asic3_hold, 10) ^ BIT(m_asic3_hold, 8) ^ BIT(m_asic3_hold, 5) |
| 31 | | ^ BIT(m_asic3_z, m_asic3_y) |
| 32 | | ^ (BIT(m_asic3_x, 0) << 1) ^ (BIT(m_asic3_x, 1) << 6) ^ (BIT(m_asic3_x, 2) << 10) ^ (BIT(m_asic3_x, 3) << 14); |
| 30 | case 0: |
| 31 | case 1: |
| 32 | m_asic3_hold ^= BIT(old, 10) ^ BIT(old, 8) ^ (BIT(m_asic3_x, 0) << 1) ^ (BIT(m_asic3_x, 3) << 14); |
| 33 | 33 | break; |
| 34 | | case 2: |
| 35 | | m_asic3_hold = |
| 36 | | (m_asic3_hold << 1) |
| 37 | | ^ 0x2bad |
| 38 | | ^ BIT(m_asic3_hold, 15) ^ BIT(m_asic3_hold, 7) ^ BIT(m_asic3_hold, 6) ^ BIT(m_asic3_hold, 5) |
| 39 | | ^ BIT(m_asic3_z, m_asic3_y) |
| 40 | | ^ (BIT(m_asic3_x, 0) << 4) ^ (BIT(m_asic3_x, 1) << 6) ^ (BIT(m_asic3_x, 2) << 10) ^ (BIT(m_asic3_x, 3) << 12); |
| 34 | |
| 35 | case 2: |
| 36 | m_asic3_hold ^= BIT(old, 10) ^ BIT(old, 8) ^ (BIT(m_asic3_x, 0) << 4) ^ (BIT(m_asic3_x, 3) << 12); |
| 41 | 37 | break; |
| 42 | | case 3: |
| 43 | | m_asic3_hold = |
| 44 | | (m_asic3_hold << 1) |
| 45 | | ^ 0x2bad |
| 46 | | ^ BIT(m_asic3_hold, 15) ^ BIT(m_asic3_hold, 10) ^ BIT(m_asic3_hold, 8) ^ BIT(m_asic3_hold, 5) |
| 47 | | ^ BIT(m_asic3_z, m_asic3_y) |
| 48 | | ^ (BIT(m_asic3_x, 0) << 4) ^ (BIT(m_asic3_x, 1) << 6) ^ (BIT(m_asic3_x, 2) << 10) ^ (BIT(m_asic3_x, 3) << 12); |
| 38 | |
| 39 | case 3: |
| 40 | m_asic3_hold ^= BIT(old, 7) ^ BIT(old, 6) ^ (BIT(m_asic3_x, 0) << 4) ^ (BIT(m_asic3_x, 3) << 12); |
| 49 | 41 | break; |
| 50 | 42 | } |
| 51 | 43 | } |
| 52 | 44 | |
| 53 | | READ16_MEMBER(pgm_asic3_state::pgm_asic3_r ) |
| 45 | READ16_MEMBER(pgm_asic3_state::pgm_asic3_r) |
| 54 | 46 | { |
| 55 | | UINT8 res = 0; |
| 56 | | /* region is supplied by the protection device */ |
| 57 | | |
| 58 | 47 | switch (m_asic3_reg) |
| 59 | 48 | { |
| 60 | | case 0x00: res = (m_asic3_latch[0] & 0xf7) | ((ioport("Region")->read() << 3) & 0x08); break; |
| 61 | | case 0x01: res = m_asic3_latch[1]; break; |
| 62 | | case 0x02: res = (m_asic3_latch[2] & 0x7f) | ((ioport("Region")->read() << 6) & 0x80); break; |
| 63 | | case 0x03: |
| 64 | | res = (BIT(m_asic3_hold, 15) << 0) |
| 65 | | | (BIT(m_asic3_hold, 12) << 1) |
| 66 | | | (BIT(m_asic3_hold, 13) << 2) |
| 67 | | | (BIT(m_asic3_hold, 10) << 3) |
| 68 | | | (BIT(m_asic3_hold, 7) << 4) |
| 69 | | | (BIT(m_asic3_hold, 9) << 5) |
| 70 | | | (BIT(m_asic3_hold, 2) << 6) |
| 71 | | | (BIT(m_asic3_hold, 5) << 7); |
| 72 | | break; |
| 73 | | case 0x20: res = 0x49; break; |
| 74 | | case 0x21: res = 0x47; break; |
| 75 | | case 0x22: res = 0x53; break; |
| 76 | | case 0x24: res = 0x41; break; |
| 77 | | case 0x25: res = 0x41; break; |
| 78 | | case 0x26: res = 0x7f; break; |
| 79 | | case 0x27: res = 0x41; break; |
| 80 | | case 0x28: res = 0x41; break; |
| 81 | | case 0x2a: res = 0x3e; break; |
| 82 | | case 0x2b: res = 0x41; break; |
| 83 | | case 0x2c: res = 0x49; break; |
| 84 | | case 0x2d: res = 0xf9; break; |
| 85 | | case 0x2e: res = 0x0a; break; |
| 86 | | case 0x30: res = 0x26; break; |
| 87 | | case 0x31: res = 0x49; break; |
| 88 | | case 0x32: res = 0x49; break; |
| 89 | | case 0x33: res = 0x49; break; |
| 90 | | case 0x34: res = 0x32; break; |
| 49 | case 0x00: // region is supplied by the protection device |
| 50 | return (m_asic3_latch[0] & 0xf7) | ((ioport("Region")->read() << 3) & 0x08); |
| 51 | |
| 52 | case 0x01: |
| 53 | return m_asic3_latch[1]; |
| 54 | |
| 55 | case 0x02: // region is supplied by the protection device |
| 56 | return (m_asic3_latch[2] & 0x7f) | ((ioport("Region")->read() << 6) & 0x80); |
| 57 | |
| 58 | case 0x03: |
| 59 | return BITSWAP8(m_asic3_hold, 5,2,9,7,10,13,12,15); |
| 60 | |
| 61 | // case $157674, expected return $157686 |
| 62 | case 0x20: return 0x49; // "IGS" |
| 63 | case 0x21: return 0x47; |
| 64 | case 0x22: return 0x53; |
| 65 | |
| 66 | case 0x24: return 0x41; |
| 67 | case 0x25: return 0x41; |
| 68 | case 0x26: return 0x7f; |
| 69 | case 0x27: return 0x41; |
| 70 | case 0x28: return 0x41; |
| 71 | |
| 72 | case 0x2a: return 0x3e; |
| 73 | case 0x2b: return 0x41; |
| 74 | case 0x2c: return 0x49; |
| 75 | case 0x2d: return 0xf9; |
| 76 | case 0x2e: return 0x0a; |
| 77 | |
| 78 | case 0x30: return 0x26; |
| 79 | case 0x31: return 0x49; |
| 80 | case 0x32: return 0x49; |
| 81 | case 0x33: return 0x49; |
| 82 | case 0x34: return 0x32; |
| 83 | |
| 84 | // default: |
| 85 | // logerror("ASIC3 R: CMD %2.2X PC: %6.6x\n", m_asic3_reg, space.device().safe_pc()); |
| 91 | 86 | } |
| 92 | 87 | |
| 93 | | return res; |
| 88 | return 0; |
| 94 | 89 | } |
| 95 | 90 | |
| 96 | | WRITE16_MEMBER(pgm_asic3_state::pgm_asic3_w ) |
| 91 | WRITE16_MEMBER(pgm_asic3_state::pgm_asic3_w) |
| 97 | 92 | { |
| 98 | | if(ACCESSING_BITS_0_7) |
| 93 | if (offset == 0) { |
| 94 | m_asic3_reg = data; |
| 95 | return; |
| 96 | } |
| 97 | |
| 98 | switch (m_asic3_reg) |
| 99 | 99 | { |
| 100 | | if (m_asic3_reg < 3) |
| 100 | case 0x00: |
| 101 | case 0x01: |
| 102 | case 0x02: |
| 101 | 103 | m_asic3_latch[m_asic3_reg] = data << 1; |
| 102 | | else if (m_asic3_reg == 0xa0) |
| 103 | | m_asic3_hold = 0; |
| 104 | | else if (m_asic3_reg == 0x40) |
| 104 | break; |
| 105 | |
| 106 | // case 0x03: // move.w #$88, $c0400e.l |
| 107 | // case 0x04: // move.w #$84, $c0400e.l |
| 108 | // case 0x05: // move.w #$A0, $c0400e.l |
| 109 | // break; |
| 110 | |
| 111 | case 0x40: |
| 112 | m_asic3_hilo = (m_asic3_hilo << 8) | data; |
| 113 | break; |
| 114 | |
| 115 | case 0x41: // Same as CMD 40. What is the purpose of writing data here again?? |
| 116 | case 0x42: |
| 117 | case 0x43: |
| 118 | case 0x44: |
| 119 | case 0x45: |
| 120 | case 0x46: |
| 121 | case 0x47: |
| 122 | break; |
| 123 | |
| 124 | case 0x48: |
| 105 | 125 | { |
| 106 | | m_asic3_h2 = m_asic3_h1; |
| 107 | | m_asic3_h1 = data; |
| 108 | | } |
| 109 | | else if (m_asic3_reg == 0x48) |
| 110 | | { |
| 111 | 126 | m_asic3_x = 0; |
| 112 | | if (!(m_asic3_h2 & 0x0a)) |
| 113 | | m_asic3_x |= 8; |
| 114 | | if (!(m_asic3_h2 & 0x90)) |
| 115 | | m_asic3_x |= 4; |
| 116 | | if (!(m_asic3_h1 & 0x06)) |
| 117 | | m_asic3_x |= 2; |
| 118 | | if (!(m_asic3_h1 & 0x90)) |
| 119 | | m_asic3_x |= 1; |
| 127 | if ((m_asic3_hilo & 0x0090) == 0) m_asic3_x |= 0x01; |
| 128 | if ((m_asic3_hilo & 0x0006) == 0) m_asic3_x |= 0x02; |
| 129 | if ((m_asic3_hilo & 0x9000) == 0) m_asic3_x |= 0x04; |
| 130 | if ((m_asic3_hilo & 0x0a00) == 0) m_asic3_x |= 0x08; |
| 120 | 131 | } |
| 121 | | else if(m_asic3_reg >= 0x80 && m_asic3_reg <= 0x87) |
| 122 | | { |
| 123 | | m_asic3_y = m_asic3_reg & 7; |
| 124 | | m_asic3_z = data; |
| 125 | | asic3_compute_hold(); |
| 126 | | } |
| 127 | | } |
| 128 | | } |
| 132 | break; |
| 129 | 133 | |
| 130 | | WRITE16_MEMBER(pgm_asic3_state::pgm_asic3_reg_w ) |
| 131 | | { |
| 132 | | if(ACCESSING_BITS_0_7) |
| 133 | | m_asic3_reg = data & 0xff; |
| 134 | | } |
| 134 | // case 0x50: // move.w #$50, $c0400e.l |
| 135 | // break; |
| 135 | 136 | |
| 137 | case 0x80: |
| 138 | case 0x81: |
| 139 | case 0x82: |
| 140 | case 0x83: |
| 141 | case 0x84: |
| 142 | case 0x85: |
| 143 | case 0x86: |
| 144 | case 0x87: |
| 145 | asic3_compute_hold(m_asic3_reg & 0x07, data); |
| 146 | break; |
| 136 | 147 | |
| 148 | case 0xa0: |
| 149 | m_asic3_hold = 0; |
| 150 | break; |
| 137 | 151 | |
| 152 | default: |
| 153 | logerror("ASIC3 W: CMD %2.2X DATA: %4.4x, PC: %6.6x\n", m_asic3_reg, data, space.device().safe_pc()); |
| 154 | } |
| 155 | } |
| 138 | 156 | |
| 139 | | |
| 140 | 157 | /* Oriental Legend INIT */ |
| 141 | 158 | |
| 142 | 159 | DRIVER_INIT_MEMBER(pgm_asic3_state,orlegend) |
| 143 | 160 | { |
| 144 | 161 | pgm_basic_init(); |
| 145 | 162 | |
| 146 | | m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xC0400e, 0xC0400f, read16_delegate(FUNC(pgm_asic3_state::pgm_asic3_r),this), write16_delegate(FUNC(pgm_asic3_state::pgm_asic3_w),this)); |
| 147 | | m_maincpu->space(AS_PROGRAM).install_write_handler(0xC04000, 0xC04001, write16_delegate(FUNC(pgm_asic3_state::pgm_asic3_reg_w),this)); |
| 163 | m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xC04000, 0xC0400f, read16_delegate(FUNC(pgm_asic3_state::pgm_asic3_r),this), write16_delegate(FUNC(pgm_asic3_state::pgm_asic3_w),this)); |
| 148 | 164 | |
| 149 | 165 | m_asic3_reg = 0; |
| 150 | 166 | m_asic3_latch[0] = 0; |
| 151 | 167 | m_asic3_latch[1] = 0; |
| 152 | 168 | m_asic3_latch[2] = 0; |
| 153 | 169 | m_asic3_x = 0; |
| 154 | | m_asic3_y = 0; |
| 155 | | m_asic3_z = 0; |
| 156 | | m_asic3_h1 = 0; |
| 157 | | m_asic3_h2 = 0; |
| 170 | m_asic3_hilo = 0; |
| 158 | 171 | m_asic3_hold = 0; |
| 159 | 172 | |
| 160 | 173 | save_item(NAME(m_asic3_reg)); |
| 161 | 174 | save_item(NAME(m_asic3_latch)); |
| 162 | 175 | save_item(NAME(m_asic3_x)); |
| 163 | | save_item(NAME(m_asic3_y)); |
| 164 | | save_item(NAME(m_asic3_z)); |
| 165 | | save_item(NAME(m_asic3_h1)); |
| 166 | | save_item(NAME(m_asic3_h2)); |
| 176 | save_item(NAME(m_asic3_hilo)); |
| 167 | 177 | save_item(NAME(m_asic3_hold)); |
| 168 | 178 | } |
| 169 | 179 | |