trunk/src/emu/cpu/hmcs40/hmcs40.c
| r244783 | r244784 | |
| 65 | 65 | |
| 66 | 66 | static ADDRESS_MAP_START(data_160x4, AS_DATA, 8, hmcs40_cpu_device) |
| 67 | 67 | AM_RANGE(0x00, 0x7f) AM_RAM |
| 68 | | AM_RANGE(0x80, 0x9f) AM_RAM AM_MIRROR(0x70) |
| 68 | AM_RANGE(0x80, 0x8f) AM_RAM AM_MIRROR(0x30) |
| 69 | AM_RANGE(0xc0, 0xcf) AM_RAM AM_MIRROR(0x30) |
| 69 | 70 | ADDRESS_MAP_END |
| 70 | 71 | |
| 71 | 72 | |
| r244783 | r244784 | |
| 95 | 96 | ); |
| 96 | 97 | break; |
| 97 | 98 | |
| 99 | case STATE_GENPC: |
| 100 | string.printf("%03X", m_pc << 1); |
| 101 | break; |
| 102 | |
| 98 | 103 | default: break; |
| 99 | 104 | } |
| 100 | 105 | } |
| r244783 | r244784 | |
| 123 | 128 | m_data = &space(AS_DATA); |
| 124 | 129 | m_prgmask = (1 << m_prgwidth) - 1; |
| 125 | 130 | m_datamask = (1 << m_datawidth) - 1; |
| 131 | m_xmask = (1 << (m_datawidth - 4)) - 1; |
| 126 | 132 | |
| 127 | 133 | m_read_d.resolve_safe(0); |
| 128 | 134 | m_write_d.resolve_safe(); |
| r244783 | r244784 | |
| 130 | 136 | // zerofill |
| 131 | 137 | memset(m_stack, 0, sizeof(m_stack)); |
| 132 | 138 | m_op = 0; |
| 139 | m_arg = 0; |
| 133 | 140 | m_pc = 0; |
| 134 | 141 | m_a = 0; |
| 135 | 142 | m_b = 0; |
| r244783 | r244784 | |
| 143 | 150 | // register for savestates |
| 144 | 151 | save_item(NAME(m_stack)); |
| 145 | 152 | save_item(NAME(m_op)); |
| 153 | save_item(NAME(m_arg)); |
| 146 | 154 | save_item(NAME(m_pc)); |
| 147 | 155 | save_item(NAME(m_a)); |
| 148 | 156 | save_item(NAME(m_b)); |
| r244783 | r244784 | |
| 162 | 170 | state_add(HMCS40_Y, "Y", m_y).formatstr("%01X"); |
| 163 | 171 | state_add(HMCS40_SPY, "SPY", m_spy).formatstr("%01X"); |
| 164 | 172 | |
| 165 | | state_add(STATE_GENPC, "curpc", m_pc).formatstr("%04X").noshow(); |
| 173 | state_add(STATE_GENPC, "curpc", m_pc).formatstr("%03X").noshow(); |
| 166 | 174 | state_add(STATE_GENFLAGS, "GENFLAGS", m_s).formatstr("%2s").noshow(); |
| 167 | 175 | |
| 168 | 176 | m_icountptr = &m_icount; |
| r244783 | r244784 | |
| 176 | 184 | |
| 177 | 185 | void hmcs40_cpu_device::device_reset() |
| 178 | 186 | { |
| 179 | | m_pc = 0; |
| 187 | m_pc = 0xffff & m_prgmask; |
| 180 | 188 | m_op = 0; |
| 181 | 189 | } |
| 182 | 190 | |
| r244783 | r244784 | |
| 186 | 194 | // execute |
| 187 | 195 | //------------------------------------------------- |
| 188 | 196 | |
| 197 | inline void hmcs40_cpu_device::increment_pc() |
| 198 | { |
| 199 | // PC lower bits is a LFSR identical to TI TMS1000 |
| 200 | UINT8 mask = 0x3f; |
| 201 | UINT8 low = m_pc & mask; |
| 202 | int fb = (low << 1 & 0x20) == (low & 0x20); |
| 203 | |
| 204 | if (low == (mask >> 1)) |
| 205 | fb = 1; |
| 206 | else if (low == mask) |
| 207 | fb = 0; |
| 208 | |
| 209 | m_pc = (m_pc & ~mask) | ((m_pc << 1 | fb) & mask); |
| 210 | } |
| 211 | |
| 212 | inline void hmcs40_cpu_device::fetch_arg() |
| 213 | { |
| 214 | // P is the only 2-byte opcode |
| 215 | if (m_op == 0x3ff) |
| 216 | { |
| 217 | m_icount--; |
| 218 | m_arg = m_program->read_word(m_pc << 1); |
| 219 | increment_pc(); |
| 220 | } |
| 221 | } |
| 222 | |
| 189 | 223 | void hmcs40_cpu_device::execute_run() |
| 190 | 224 | { |
| 191 | 225 | while (m_icount > 0) |
| 192 | 226 | { |
| 193 | 227 | m_icount--; |
| 194 | 228 | |
| 195 | | debugger_instruction_hook(this, m_pc); |
| 196 | | m_op = m_program->read_byte(m_pc); |
| 197 | | m_pc = (m_pc + 1) & m_prgmask; |
| 229 | debugger_instruction_hook(this, m_pc << 1); |
| 230 | m_op = m_program->read_word(m_pc << 1); |
| 231 | increment_pc(); |
| 232 | fetch_arg(); |
| 198 | 233 | } |
| 199 | 234 | } |
trunk/src/emu/cpu/hmcs40/hmcs40op.inc
| r244783 | r244784 | |
| 2 | 2 | |
| 3 | 3 | // internal helpers |
| 4 | 4 | |
| 5 | inline UINT8 hmcs40_cpu_device::ram_r() |
| 6 | { |
| 7 | UINT8 address = (m_x << 4 | m_y) & m_datamask; |
| 8 | return m_data->read_byte(address) & 0xf; |
| 9 | } |
| 10 | |
| 11 | inline void hmcs40_cpu_device::ram_w(UINT8 data) |
| 12 | { |
| 13 | UINT8 address = (m_x << 4 | m_y) & m_datamask; |
| 14 | m_data->write_byte(address, data & 0xf); |
| 15 | } |
| 16 | |
| 17 | void hmcs40_cpu_device::pop_stack() |
| 18 | { |
| 19 | m_pc = m_stack[0] & m_prgmask; |
| 20 | for (int i = 0; i < m_stack_levels-1; i++) |
| 21 | m_stack[i] = m_stack[i+1]; |
| 22 | } |
| 23 | |
| 24 | void hmcs40_cpu_device::push_stack() |
| 25 | { |
| 26 | for (int i = m_stack_levels-1; i >= 1; i--) |
| 27 | m_stack[i] = m_stack[i-1]; |
| 28 | m_stack[0] = m_pc; |
| 29 | } |
| 30 | |
| 5 | 31 | void hmcs40_cpu_device::op_illegal() |
| 6 | 32 | { |
| 7 | 33 | logerror("%s unknown opcode $%03X at $%04X\n", tag(), m_op, m_pc); |
| r244783 | r244784 | |
| 16 | 42 | void hmcs40_cpu_device::op_lab() |
| 17 | 43 | { |
| 18 | 44 | // LAB: Load A from B |
| 19 | | op_illegal(); |
| 45 | m_a = m_b; |
| 20 | 46 | } |
| 21 | 47 | |
| 22 | 48 | void hmcs40_cpu_device::op_lba() |
| 23 | 49 | { |
| 24 | 50 | // LBA: Load B from A |
| 25 | | op_illegal(); |
| 51 | m_b = m_a; |
| 26 | 52 | } |
| 27 | 53 | |
| 28 | 54 | void hmcs40_cpu_device::op_lay() |
| 29 | 55 | { |
| 30 | 56 | // LAY: Load A from Y |
| 31 | | op_illegal(); |
| 57 | m_a = m_y; |
| 32 | 58 | } |
| 33 | 59 | |
| 34 | 60 | void hmcs40_cpu_device::op_laspx() |
| 35 | 61 | { |
| 36 | 62 | // LASPX: Load A from SPX |
| 37 | | op_illegal(); |
| 63 | m_a = m_spx; |
| 38 | 64 | } |
| 39 | 65 | |
| 40 | 66 | void hmcs40_cpu_device::op_laspy() |
| 41 | 67 | { |
| 42 | 68 | // LASPY: Load A from SPY |
| 43 | | op_illegal(); |
| 69 | m_a = m_spy; |
| 44 | 70 | } |
| 45 | 71 | |
| 46 | 72 | void hmcs40_cpu_device::op_xamr() |
| 47 | 73 | { |
| 48 | 74 | // XAMR m: Exchange A and MR(m) |
| 49 | | op_illegal(); |
| 75 | |
| 76 | // determine MR(Memory Register) location |
| 77 | UINT8 y = m_op & 0xf; |
| 78 | UINT8 x = (y > 3) ? 0xf : (y + 12); |
| 79 | UINT8 address = (x << 4 | y) & m_datamask; |
| 80 | |
| 81 | UINT8 old_a = m_a; |
| 82 | m_a = m_data->read_byte(address) & 0xf; |
| 83 | m_data->write_byte(address, old_a & 0xf); |
| 50 | 84 | } |
| 51 | 85 | |
| 52 | 86 | |
| r244783 | r244784 | |
| 55 | 89 | void hmcs40_cpu_device::op_lxa() |
| 56 | 90 | { |
| 57 | 91 | // LXA: Load X from A |
| 58 | | op_illegal(); |
| 92 | m_x = m_a; |
| 59 | 93 | } |
| 60 | 94 | |
| 61 | 95 | void hmcs40_cpu_device::op_lya() |
| 62 | 96 | { |
| 63 | 97 | // LYA: Load Y from A |
| 64 | | op_illegal(); |
| 98 | m_y = m_a; |
| 65 | 99 | } |
| 66 | 100 | |
| 67 | 101 | void hmcs40_cpu_device::op_lxi() |
| 68 | 102 | { |
| 69 | 103 | // LXI i: Load X from Immediate |
| 70 | | op_illegal(); |
| 104 | m_x = m_op & 0xf; |
| 71 | 105 | } |
| 72 | 106 | |
| 73 | 107 | void hmcs40_cpu_device::op_lyi() |
| 74 | 108 | { |
| 75 | 109 | // LYI i: Load Y from Immediate |
| 76 | | op_illegal(); |
| 110 | m_y = m_op & 0xf; |
| 77 | 111 | } |
| 78 | 112 | |
| 79 | 113 | void hmcs40_cpu_device::op_iy() |
| 80 | 114 | { |
| 81 | 115 | // IY: Increment Y |
| 82 | | op_illegal(); |
| 116 | m_y = (m_y + 1) & 0xf; |
| 117 | m_s = (m_y != 0); |
| 83 | 118 | } |
| 84 | 119 | |
| 85 | 120 | void hmcs40_cpu_device::op_dy() |
| 86 | 121 | { |
| 87 | 122 | // DY: Decrement Y |
| 88 | | op_illegal(); |
| 123 | m_y = (m_y - 1) & 0xf; |
| 124 | m_s = (m_y != 0xf); |
| 89 | 125 | } |
| 90 | 126 | |
| 91 | 127 | void hmcs40_cpu_device::op_ayy() |
| 92 | 128 | { |
| 93 | 129 | // AYY: Add A to Y |
| 94 | | op_illegal(); |
| 130 | m_y += m_a; |
| 131 | m_s = m_y >> 4 & 1; |
| 132 | m_y &= 0xf; |
| 95 | 133 | } |
| 96 | 134 | |
| 97 | 135 | void hmcs40_cpu_device::op_syy() |
| 98 | 136 | { |
| 99 | 137 | // SYY: Subtract A from Y |
| 100 | | op_illegal(); |
| 138 | m_y -= m_a; |
| 139 | m_s = ~m_y >> 4 & 1; |
| 140 | m_y &= 0xf; |
| 101 | 141 | } |
| 102 | 142 | |
| 103 | 143 | void hmcs40_cpu_device::op_xspx() |
| 104 | 144 | { |
| 105 | 145 | // XSPX: Exchange X and SPX |
| 106 | | op_illegal(); |
| 146 | UINT8 old_x = m_x; |
| 147 | m_x = m_spx; |
| 148 | m_spx = old_x; |
| 107 | 149 | } |
| 108 | 150 | |
| 109 | | void hmcs40_cpu_device::op_sxpy() |
| 151 | void hmcs40_cpu_device::op_xspy() |
| 110 | 152 | { |
| 111 | | // SXPY: Exchange Y and SPY |
| 112 | | op_illegal(); |
| 153 | // XSPY: Exchange Y and SPY |
| 154 | UINT8 old_y = m_y; |
| 155 | m_y = m_spy; |
| 156 | m_spy = old_y; |
| 113 | 157 | } |
| 114 | 158 | |
| 115 | 159 | void hmcs40_cpu_device::op_xspxy() |
| 116 | 160 | { |
| 117 | 161 | // XSPXY: Exchange X and SPX, Y and SPY |
| 118 | | op_illegal(); |
| 162 | op_xspx(); |
| 163 | op_xspy(); |
| 119 | 164 | } |
| 120 | 165 | |
| 121 | 166 | |
| r244783 | r244784 | |
| 124 | 169 | void hmcs40_cpu_device::op_lam() |
| 125 | 170 | { |
| 126 | 171 | // LAM (XY): Load A from Memory |
| 127 | | op_illegal(); |
| 172 | m_a = ram_r(); |
| 173 | op_xspxy(); |
| 128 | 174 | } |
| 129 | 175 | |
| 130 | 176 | void hmcs40_cpu_device::op_lbm() |
| 131 | 177 | { |
| 132 | 178 | // LBM (XY): Load B from Memory |
| 133 | | op_illegal(); |
| 179 | m_b = ram_r(); |
| 180 | op_xspxy(); |
| 134 | 181 | } |
| 135 | 182 | |
| 136 | 183 | void hmcs40_cpu_device::op_xma() |
| 137 | 184 | { |
| 138 | 185 | // XMA (XY): Exchange Memory and A |
| 139 | | op_illegal(); |
| 186 | UINT8 old_a = m_a; |
| 187 | m_a = ram_r(); |
| 188 | ram_w(old_a); |
| 189 | op_xspxy(); |
| 140 | 190 | } |
| 141 | 191 | |
| 142 | 192 | void hmcs40_cpu_device::op_xmb() |
| 143 | 193 | { |
| 144 | 194 | // XMB (XY): Exchange Memory and B |
| 145 | | op_illegal(); |
| 195 | UINT8 old_b = m_b; |
| 196 | m_b = ram_r(); |
| 197 | ram_w(old_b); |
| 198 | op_xspxy(); |
| 146 | 199 | } |
| 147 | 200 | |
| 148 | 201 | void hmcs40_cpu_device::op_lmaiy() |
| 149 | 202 | { |
| 150 | 203 | // LMAIY (X): Load Memory from A, Increment Y |
| 151 | | op_illegal(); |
| 204 | ram_w(m_a); |
| 205 | op_iy(); |
| 206 | op_xspx(); |
| 152 | 207 | } |
| 153 | 208 | |
| 154 | 209 | void hmcs40_cpu_device::op_lmady() |
| 155 | 210 | { |
| 156 | 211 | // LMADY (X): Load Memory from A, Decrement Y |
| 157 | | op_illegal(); |
| 212 | ram_w(m_a); |
| 213 | op_dy(); |
| 214 | op_xspx(); |
| 158 | 215 | } |
| 159 | 216 | |
| 160 | 217 | |
| r244783 | r244784 | |
| 163 | 220 | void hmcs40_cpu_device::op_lmiiy() |
| 164 | 221 | { |
| 165 | 222 | // LMIIY i: Load Memory from Immediate, Increment Y |
| 166 | | op_illegal(); |
| 223 | ram_w(m_op & 0xf); |
| 224 | op_iy(); |
| 167 | 225 | } |
| 168 | 226 | |
| 169 | 227 | void hmcs40_cpu_device::op_lai() |
| 170 | 228 | { |
| 171 | 229 | // LAI i: Load A from Immediate |
| 172 | | op_illegal(); |
| 230 | m_a = m_op & 0xf; |
| 173 | 231 | } |
| 174 | 232 | |
| 175 | 233 | void hmcs40_cpu_device::op_lbi() |
| 176 | 234 | { |
| 177 | 235 | // LBI i: Load B from Immediate |
| 178 | | op_illegal(); |
| 236 | m_b = m_op & 0xf; |
| 179 | 237 | } |
| 180 | 238 | |
| 181 | 239 | |