trunk/src/emu/cpu/amis2000/amis2000.c
| r243254 | r243255 | |
| 114 | 114 | enum |
| 115 | 115 | { |
| 116 | 116 | S2000_PC=1, S2000_BL, S2000_BU, |
| 117 | | S2000_ACC, S2000_E |
| 117 | S2000_ACC, S2000_E, S2000_CARRY |
| 118 | 118 | }; |
| 119 | 119 | |
| 120 | 120 | void amis2000_device::device_start() |
| r243254 | r243255 | |
| 134 | 134 | // zerofill |
| 135 | 135 | memset(m_callstack, 0, sizeof(m_callstack)); |
| 136 | 136 | m_pc = 0; |
| 137 | m_skip = false; |
| 137 | 138 | m_op = 0; |
| 138 | 139 | m_f = 0; |
| 140 | m_carry = 0; |
| 139 | 141 | m_bl = 0; |
| 140 | 142 | m_bu = 0; |
| 141 | 143 | m_acc = 0; |
| 142 | 144 | m_e = 0; |
| 145 | m_i = 0; |
| 146 | m_k = 0; |
| 143 | 147 | |
| 144 | 148 | // register for savestates |
| 145 | 149 | save_item(NAME(m_callstack)); |
| 146 | 150 | save_item(NAME(m_pc)); |
| 151 | save_item(NAME(m_skip)); |
| 147 | 152 | save_item(NAME(m_op)); |
| 148 | 153 | save_item(NAME(m_f)); |
| 154 | save_item(NAME(m_carry)); |
| 149 | 155 | save_item(NAME(m_bl)); |
| 150 | 156 | save_item(NAME(m_bu)); |
| 151 | 157 | save_item(NAME(m_acc)); |
| 152 | 158 | save_item(NAME(m_e)); |
| 159 | save_item(NAME(m_i)); |
| 160 | save_item(NAME(m_k)); |
| 153 | 161 | |
| 154 | 162 | // register state for debugger |
| 155 | 163 | state_add(S2000_PC, "PC", m_pc ).formatstr("%04X"); |
| r243254 | r243255 | |
| 157 | 165 | state_add(S2000_BU, "BU", m_bu ).formatstr("%01X"); |
| 158 | 166 | state_add(S2000_ACC, "ACC", m_acc ).formatstr("%01X"); |
| 159 | 167 | state_add(S2000_E, "E", m_e ).formatstr("%01X"); |
| 168 | state_add(S2000_CARRY, "CARRY", m_carry ).formatstr("%01X"); |
| 160 | 169 | |
| 161 | 170 | state_add(STATE_GENPC, "curpc", m_pc).formatstr("%04X").noshow(); |
| 162 | 171 | state_add(STATE_GENFLAGS, "GENFLAGS", m_f).formatstr("%6s").noshow(); |
| r243254 | r243255 | |
| 192 | 201 | debugger_instruction_hook(this, m_pc); |
| 193 | 202 | m_op = m_program->read_byte(m_pc); |
| 194 | 203 | m_pc = (m_pc + 1) & 0x1fff; |
| 204 | |
| 205 | if (m_skip) |
| 206 | { |
| 207 | // always skip over PP prefix |
| 208 | m_skip = ((m_op & 0xf0) == 0x60); |
| 209 | continue; |
| 210 | } |
| 195 | 211 | |
| 196 | 212 | switch (m_op & 0xf0) |
| 197 | 213 | { |
trunk/src/emu/cpu/amis2000/amis2000op.inc
| r243254 | r243255 | |
| 2 | 2 | |
| 3 | 3 | // internal helpers |
| 4 | 4 | |
| 5 | UINT8 amis2000_device::ram_r() |
| 6 | { |
| 7 | UINT16 address = m_bu << m_bu_bits | m_bl; |
| 8 | return m_data->read_byte(address) & 0xf; |
| 9 | } |
| 10 | |
| 11 | void amis2000_device::ram_w(UINT8 data) |
| 12 | { |
| 13 | UINT16 address = m_bu << m_bu_bits | m_bl; |
| 14 | m_data->write_byte(address, data & 0xf); |
| 15 | } |
| 16 | |
| 5 | 17 | void amis2000_device::op_illegal() |
| 6 | 18 | { |
| 7 | 19 | logerror("%s unknown opcode $%02X at $%04X\n", tag(), m_op, m_pc); |
| r243254 | r243255 | |
| 13 | 25 | void amis2000_device::op_lai() |
| 14 | 26 | { |
| 15 | 27 | // LAI X: load ACC with X, select I and K inputs |
| 16 | | op_illegal(); |
| 28 | UINT8 param = m_op & 0x0f; |
| 29 | m_acc = param; |
| 30 | m_i = m_read_i(0, 0xff) & param; |
| 31 | m_k = m_read_k(0, 0xff) & param; |
| 17 | 32 | } |
| 18 | 33 | |
| 19 | 34 | void amis2000_device::op_lab() |
| 20 | 35 | { |
| 21 | 36 | // LAB: load ACC with BL |
| 22 | | op_illegal(); |
| 37 | m_acc = m_bl; |
| 23 | 38 | } |
| 24 | 39 | |
| 25 | 40 | void amis2000_device::op_lae() |
| 26 | 41 | { |
| 27 | 42 | // LAE: load ACC with E |
| 28 | | op_illegal(); |
| 43 | m_acc = m_e; |
| 29 | 44 | } |
| 30 | 45 | |
| 31 | 46 | void amis2000_device::op_xab() |
| 32 | 47 | { |
| 33 | 48 | // XAB: exchange ACC with BL |
| 34 | | op_illegal(); |
| 49 | UINT8 old_acc = m_acc; |
| 50 | m_acc = m_bl; |
| 51 | m_bl = old_acc; |
| 35 | 52 | } |
| 36 | 53 | |
| 37 | 54 | void amis2000_device::op_xabu() |
| 38 | 55 | { |
| 39 | 56 | // XABU: exchange ACC with BU |
| 40 | | op_illegal(); |
| 57 | UINT8 old_acc = m_acc; |
| 58 | m_acc = (m_acc & ~m_bu_mask) | (m_bu & m_bu_mask); |
| 59 | m_bu = old_acc & m_bu_mask; |
| 41 | 60 | } |
| 42 | 61 | |
| 43 | 62 | void amis2000_device::op_xae() |
| 44 | 63 | { |
| 45 | 64 | // XAE: exchange ACC with E |
| 46 | | op_illegal(); |
| 65 | UINT8 old_acc = m_acc; |
| 66 | m_acc = m_e; |
| 67 | m_e = old_acc; |
| 47 | 68 | } |
| 48 | 69 | |
| 49 | 70 | void amis2000_device::op_lbe() |
| 50 | 71 | { |
| 51 | 72 | // LBE Y: load BU with Y, load BL with E |
| 52 | | op_illegal(); |
| 73 | UINT8 param = m_op & 0x03; |
| 74 | m_bu = param & m_bu_mask; |
| 75 | m_bl = m_e; |
| 53 | 76 | } |
| 54 | 77 | |
| 55 | 78 | void amis2000_device::op_lbep() |
| 56 | 79 | { |
| 57 | 80 | // LBEP Y: load BU with Y, load BL with E+1 |
| 58 | | op_illegal(); |
| 81 | UINT8 param = m_op & 0x03; |
| 82 | m_bu = param & m_bu_mask; |
| 83 | m_bl = m_e + 1; |
| 59 | 84 | } |
| 60 | 85 | |
| 61 | 86 | void amis2000_device::op_lbz() |
| 62 | 87 | { |
| 63 | 88 | // LBZ Y: load BU with Y, load BL with 0 |
| 64 | | op_illegal(); |
| 89 | UINT8 param = m_op & 0x03; |
| 90 | m_bu = param & m_bu_mask; |
| 91 | m_bl = 0; |
| 65 | 92 | } |
| 66 | 93 | |
| 67 | 94 | void amis2000_device::op_lbf() |
| 68 | 95 | { |
| 69 | 96 | // LBF Y: load BU with Y, load BL with 15 |
| 70 | | op_illegal(); |
| 97 | UINT8 param = m_op & 0x03; |
| 98 | m_bu = param & m_bu_mask; |
| 99 | m_bl = 0xf; |
| 71 | 100 | } |
| 72 | 101 | |
| 73 | 102 | |
| r243254 | r243255 | |
| 76 | 105 | void amis2000_device::op_lam() |
| 77 | 106 | { |
| 78 | 107 | // LAM _Y: load ACC with RAM, xor BU with _Y |
| 79 | | op_illegal(); |
| 108 | m_acc = ram_r(); |
| 109 | UINT8 param = ~m_op & 0x03; |
| 110 | m_bu ^= param & m_bu_mask; |
| 80 | 111 | } |
| 81 | 112 | |
| 82 | 113 | void amis2000_device::op_xc() |
| 83 | 114 | { |
| 84 | 115 | // XC _Y: exchange ACC with RAM, xor BU with _Y |
| 85 | | op_illegal(); |
| 116 | UINT8 old_acc = m_acc; |
| 117 | m_acc = ram_r(); |
| 118 | ram_w(old_acc); |
| 119 | UINT8 param = ~m_op & 0x03; |
| 120 | m_bu ^= param & m_bu_mask; |
| 86 | 121 | } |
| 87 | 122 | |
| 88 | 123 | void amis2000_device::op_xci() |
| 89 | 124 | { |
| 90 | 125 | // XCI _Y: exchange ACC with RAM, increment BL(skip next on carry), xor BU with _Y |
| 91 | | op_illegal(); |
| 126 | op_xc(); |
| 127 | m_bl = (m_bl + 1) & 0xf; |
| 128 | m_skip = (m_bl == 0); |
| 92 | 129 | } |
| 93 | 130 | |
| 94 | 131 | void amis2000_device::op_xcd() |
| 95 | 132 | { |
| 96 | 133 | // XCD _Y: exchange ACC with RAM, decrement BL(skip next on carry), xor BU with _Y |
| 97 | | op_illegal(); |
| 134 | op_xc(); |
| 135 | m_bl = (m_bl - 1) & 0xf; |
| 136 | m_skip = (m_bl == 0xf); |
| 98 | 137 | } |
| 99 | 138 | |
| 100 | 139 | void amis2000_device::op_stm() |
| 101 | 140 | { |
| 102 | 141 | // STM Z: set RAM bit Z |
| 103 | | op_illegal(); |
| 142 | UINT8 param = 1 << (m_op & 0x03); |
| 143 | ram_w(ram_r() | param); |
| 104 | 144 | } |
| 105 | 145 | |
| 106 | 146 | void amis2000_device::op_rsm() |
| 107 | 147 | { |
| 108 | 148 | // RSM Z: reset RAM bit Z |
| 109 | | op_illegal(); |
| 149 | UINT8 param = 1 << (m_op & 0x03); |
| 150 | ram_w(ram_r() & ~param); |
| 110 | 151 | } |
| 111 | 152 | |
| 112 | 153 | |
| r243254 | r243255 | |
| 204 | 245 | void amis2000_device::op_szc() |
| 205 | 246 | { |
| 206 | 247 | // SZC: skip next on zero(no) carry |
| 207 | | op_illegal(); |
| 248 | m_skip = !m_carry; |
| 208 | 249 | } |
| 209 | 250 | |
| 210 | 251 | void amis2000_device::op_szm() |
| 211 | 252 | { |
| 212 | 253 | // SZM Z: skip next on zero RAM bit Z |
| 213 | | op_illegal(); |
| 254 | UINT8 param = 1 << (m_op & 0x03); |
| 255 | m_skip = !(ram_r() & param); |
| 214 | 256 | } |
| 215 | 257 | |
| 216 | 258 | void amis2000_device::op_szi() |
| 217 | 259 | { |
| 218 | 260 | // SZI: skip next on zero I pin(s) |
| 219 | | op_illegal(); |
| 261 | m_skip = !m_i; |
| 220 | 262 | } |
| 221 | 263 | |
| 222 | 264 | void amis2000_device::op_szk() |
| 223 | 265 | { |
| 224 | 266 | // SZK: skip next on zero K pin(s) |
| 225 | | op_illegal(); |
| 267 | m_skip = !m_k; |
| 226 | 268 | } |
| 227 | 269 | |
| 228 | 270 | void amis2000_device::op_sbe() |
| 229 | 271 | { |
| 230 | 272 | // SBE: skip next on BL equ E |
| 231 | | op_illegal(); |
| 273 | m_skip = (m_bl == m_e); |
| 232 | 274 | } |
| 233 | 275 | |
| 234 | 276 | void amis2000_device::op_sam() |
| 235 | 277 | { |
| 236 | 278 | // SAM: skip next on ACC equ RAM |
| 237 | | op_illegal(); |
| 279 | m_skip = (m_acc == ram_r()); |
| 238 | 280 | } |
| 239 | 281 | |
| 240 | 282 | void amis2000_device::op_sos() |
| r243254 | r243255 | |
| 246 | 288 | void amis2000_device::op_tf1() |
| 247 | 289 | { |
| 248 | 290 | // TF1: skip next on flag 1 |
| 249 | | op_illegal(); |
| 291 | m_skip = (m_f & 0x01); |
| 250 | 292 | } |
| 251 | 293 | |
| 252 | 294 | void amis2000_device::op_tf2() |
| 253 | 295 | { |
| 254 | 296 | // TF2: skip next on flag 2 |
| 255 | | op_illegal(); |
| 297 | m_skip = (m_f & 0x02); |
| 256 | 298 | } |
| 257 | 299 | |
| 258 | 300 | |
| r243254 | r243255 | |
| 261 | 303 | void amis2000_device::op_adcs() |
| 262 | 304 | { |
| 263 | 305 | // ADCS: add RAM to ACC+carry, skip next on no carry |
| 264 | | op_illegal(); |
| 306 | m_acc += ram_r() + m_carry; |
| 307 | m_carry = m_acc >> 4 & 1; |
| 308 | m_skip = !m_carry; |
| 309 | m_acc &= 0xf; |
| 265 | 310 | } |
| 266 | 311 | |
| 267 | 312 | void amis2000_device::op_adis() |
| 268 | 313 | { |
| 269 | 314 | // ADIS X: add X to ACC, skip next on no carry |
| 270 | | op_illegal(); |
| 315 | UINT8 param = m_op & 0x0f; |
| 316 | m_acc += param; |
| 317 | m_skip = !(m_acc >> 4 & 1); |
| 318 | m_acc &= 0xf; |
| 271 | 319 | } |
| 272 | 320 | |
| 273 | 321 | void amis2000_device::op_add() |
| 274 | 322 | { |
| 275 | 323 | // ADD: add RAM to ACC |
| 276 | | op_illegal(); |
| 324 | m_acc = (m_acc + ram_r()) & 0xf; |
| 277 | 325 | } |
| 278 | 326 | |
| 279 | 327 | void amis2000_device::op_and() |
| 280 | 328 | { |
| 281 | 329 | // AND: and ACC with RAM |
| 282 | | op_illegal(); |
| 330 | m_acc &= ram_r(); |
| 283 | 331 | } |
| 284 | 332 | |
| 285 | 333 | void amis2000_device::op_xor() |
| 286 | 334 | { |
| 287 | 335 | // XOR: xor ACC with RAM |
| 288 | | op_illegal(); |
| 336 | m_acc ^= ram_r(); |
| 289 | 337 | } |
| 290 | 338 | |
| 291 | 339 | void amis2000_device::op_stc() |
| 292 | 340 | { |
| 293 | 341 | // STC: set carry |
| 294 | | op_illegal(); |
| 342 | m_carry = 1; |
| 295 | 343 | } |
| 296 | 344 | |
| 297 | 345 | void amis2000_device::op_rsc() |
| 298 | 346 | { |
| 299 | 347 | // RSC: reset carry |
| 300 | | op_illegal(); |
| 348 | m_carry = 0; |
| 301 | 349 | } |
| 302 | 350 | |
| 303 | 351 | void amis2000_device::op_cma() |
| 304 | 352 | { |
| 305 | 353 | // CMA: complement ACC |
| 306 | | op_illegal(); |
| 354 | m_acc ^= 0xf; |
| 307 | 355 | } |
| 308 | 356 | |
| 309 | 357 | void amis2000_device::op_sf1() |
| 310 | 358 | { |
| 311 | 359 | // SF1: set flag 1 |
| 312 | | op_illegal(); |
| 360 | m_f |= 0x01; |
| 313 | 361 | } |
| 314 | 362 | |
| 315 | 363 | void amis2000_device::op_rf1() |
| 316 | 364 | { |
| 317 | 365 | // RF1: reset flag 1 |
| 318 | | op_illegal(); |
| 366 | m_f &= ~0x01; |
| 319 | 367 | } |
| 320 | 368 | |
| 321 | 369 | void amis2000_device::op_sf2() |
| 322 | 370 | { |
| 323 | 371 | // SF2: set flag 2 |
| 324 | | op_illegal(); |
| 372 | m_f |= 0x02; |
| 325 | 373 | } |
| 326 | 374 | |
| 327 | 375 | void amis2000_device::op_rf2() |
| 328 | 376 | { |
| 329 | 377 | // RF2: reset flag 2 |
| 330 | | op_illegal(); |
| 378 | m_f &= ~0x02; |
| 331 | 379 | } |