trunk/src/emu/cpu/amis2000/amis2000.c
| r243252 | r243253 | |
| 16 | 16 | |
| 17 | 17 | // S2000 is the most basic one, 64 nibbles internal RAM and 1KB internal ROM |
| 18 | 18 | // S2150 increased RAM to 80 nibbles and ROM to 1.5KB |
| 19 | | // high-voltage output versions of these chips (S2000C and S2150C) are identical overall |
| 19 | // high-voltage output versions of these chips (S2000A and S2150A) are identical overall |
| 20 | 20 | const device_type AMI_S2000 = &device_creator<amis2000_device>; |
| 21 | 21 | const device_type AMI_S2150 = &device_creator<amis2150_device>; |
| 22 | 22 | |
| r243252 | r243253 | |
| 48 | 48 | m_program_config("program", ENDIANNESS_BIG, 8, 13, 0, ADDRESS_MAP_NAME(program_1k)), |
| 49 | 49 | m_data_config("data", ENDIANNESS_BIG, 8, 6, 0, ADDRESS_MAP_NAME(data_64x4)), |
| 50 | 50 | m_bu_bits(2), |
| 51 | | m_stack_bits(10), |
| 51 | m_callstack_bits(10), |
| 52 | m_callstack_depth(3), |
| 52 | 53 | m_read_k(*this), |
| 53 | 54 | m_read_i(*this), |
| 54 | 55 | m_read_d(*this), |
| r243252 | r243253 | |
| 57 | 58 | { |
| 58 | 59 | } |
| 59 | 60 | |
| 60 | | amis2000_device::amis2000_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 bu_bits, UINT8 stack_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source) |
| 61 | amis2000_device::amis2000_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 bu_bits, UINT8 callstack_bits, UINT8 callstack_depth, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source) |
| 61 | 62 | : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source), |
| 62 | 63 | m_program_config("program", ENDIANNESS_BIG, 8, prgwidth, 0, program), |
| 63 | 64 | m_data_config("data", ENDIANNESS_BIG, 8, datawidth, 0, data), |
| 64 | 65 | m_bu_bits(bu_bits), |
| 65 | | m_stack_bits(stack_bits), |
| 66 | m_callstack_bits(callstack_bits), |
| 67 | m_callstack_depth(callstack_depth), |
| 66 | 68 | m_read_k(*this), |
| 67 | 69 | m_read_i(*this), |
| 68 | 70 | m_read_d(*this), |
| r243252 | r243253 | |
| 72 | 74 | } |
| 73 | 75 | |
| 74 | 76 | amis2150_device::amis2150_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 75 | | : amis2000_device(mconfig, AMI_S2150, "AMI S2150", tag, owner, clock, 3, 11, 13, ADDRESS_MAP_NAME(program_1_5k), 7, ADDRESS_MAP_NAME(data_80x4), "amis2150", __FILE__) |
| 77 | : amis2000_device(mconfig, AMI_S2150, "AMI S2150", tag, owner, clock, 3, 11, 3, 13, ADDRESS_MAP_NAME(program_1_5k), 7, ADDRESS_MAP_NAME(data_80x4), "amis2150", __FILE__) |
| 76 | 78 | { |
| 77 | 79 | } |
| 78 | 80 | |
| r243252 | r243253 | |
| 112 | 114 | enum |
| 113 | 115 | { |
| 114 | 116 | S2000_PC=1, S2000_BL, S2000_BU, |
| 115 | | S2000_A, S2000_E |
| 117 | S2000_ACC, S2000_E |
| 116 | 118 | }; |
| 117 | 119 | |
| 118 | 120 | void amis2000_device::device_start() |
| r243252 | r243253 | |
| 127 | 129 | m_write_a.resolve_safe(); |
| 128 | 130 | |
| 129 | 131 | m_bu_mask = (1 << m_bu_bits) - 1; |
| 130 | | m_stack_mask = (1 << m_stack_bits) - 1; |
| 132 | m_callstack_mask = (1 << m_callstack_bits) - 1; |
| 131 | 133 | |
| 132 | 134 | // zerofill |
| 133 | | m_stack[0] = m_stack[1] = m_stack[2] = 0; |
| 135 | memset(m_callstack, 0, sizeof(m_callstack)); |
| 134 | 136 | m_pc = 0; |
| 135 | 137 | m_op = 0; |
| 136 | 138 | m_f = 0; |
| 137 | 139 | m_bl = 0; |
| 138 | 140 | m_bu = 0; |
| 139 | | m_a = 0; |
| 141 | m_acc = 0; |
| 140 | 142 | m_e = 0; |
| 141 | 143 | |
| 142 | 144 | // register for savestates |
| 143 | | save_item(NAME(m_stack)); |
| 145 | save_item(NAME(m_callstack)); |
| 144 | 146 | save_item(NAME(m_pc)); |
| 145 | 147 | save_item(NAME(m_op)); |
| 146 | 148 | save_item(NAME(m_f)); |
| 147 | 149 | save_item(NAME(m_bl)); |
| 148 | 150 | save_item(NAME(m_bu)); |
| 149 | | save_item(NAME(m_a)); |
| 151 | save_item(NAME(m_acc)); |
| 150 | 152 | save_item(NAME(m_e)); |
| 151 | 153 | |
| 152 | 154 | // register state for debugger |
| 153 | 155 | state_add(S2000_PC, "PC", m_pc ).formatstr("%04X"); |
| 154 | 156 | state_add(S2000_BL, "BL", m_bl ).formatstr("%01X"); |
| 155 | 157 | state_add(S2000_BU, "BU", m_bu ).formatstr("%01X"); |
| 156 | | state_add(S2000_A, "A", m_a ).formatstr("%01X"); |
| 157 | | state_add(S2000_E, "E", m_a ).formatstr("%01X"); |
| 158 | state_add(S2000_ACC, "ACC", m_acc ).formatstr("%01X"); |
| 159 | state_add(S2000_E, "E", m_e ).formatstr("%01X"); |
| 158 | 160 | |
| 159 | 161 | state_add(STATE_GENPC, "curpc", m_pc).formatstr("%04X").noshow(); |
| 160 | 162 | state_add(STATE_GENFLAGS, "GENFLAGS", m_f).formatstr("%6s").noshow(); |
| r243252 | r243253 | |
| 183 | 185 | |
| 184 | 186 | void amis2000_device::execute_run() |
| 185 | 187 | { |
| 186 | | do |
| 188 | while (m_icount > 0) |
| 187 | 189 | { |
| 188 | 190 | m_icount--; |
| 189 | 191 | |
| r243252 | r243253 | |
| 191 | 193 | m_op = m_program->read_byte(m_pc); |
| 192 | 194 | m_pc = (m_pc + 1) & 0x1fff; |
| 193 | 195 | |
| 194 | | switch (m_op) |
| 196 | switch (m_op & 0xf0) |
| 195 | 197 | { |
| 196 | | default: break; |
| 197 | | } |
| 198 | case 0x50: op_adis(); break; |
| 199 | case 0x60: op_pp(); break; |
| 200 | case 0x70: op_lai(); break; |
| 198 | 201 | |
| 199 | | } while (m_icount > 0); |
| 202 | case 0x80: case 0x90: case 0xa0: case 0xb0: op_jms(); break; |
| 203 | case 0xc0: case 0xd0: case 0xe0: case 0xf0: op_jmp(); break; |
| 204 | |
| 205 | default: |
| 206 | switch (m_op) |
| 207 | { |
| 208 | case 0x00: op_nop(); break; |
| 209 | case 0x01: op_illegal(); break; // reserved for devkit-use |
| 210 | case 0x02: op_rt(); break; |
| 211 | case 0x03: op_rts(); break; |
| 212 | case 0x04: op_psh(); break; |
| 213 | case 0x05: op_psl(); break; |
| 214 | case 0x06: op_and(); break; |
| 215 | case 0x07: op_sos(); break; |
| 216 | case 0x08: op_sbe(); break; |
| 217 | case 0x09: op_szc(); break; |
| 218 | case 0x0a: op_stc(); break; |
| 219 | case 0x0b: op_rsc(); break; |
| 220 | case 0x0c: op_lae(); break; |
| 221 | case 0x0d: op_xae(); break; |
| 222 | case 0x0e: op_inp(); break; |
| 223 | case 0x0f: op_eur(); break; |
| 224 | case 0x10: op_cma(); break; |
| 225 | case 0x11: op_xabu(); break; |
| 226 | case 0x12: op_lab(); break; |
| 227 | case 0x13: op_xab(); break; |
| 228 | case 0x14: op_adcs(); break; |
| 229 | case 0x15: op_xor(); break; |
| 230 | case 0x16: op_add(); break; |
| 231 | case 0x17: op_sam(); break; |
| 232 | case 0x18: op_disb(); break; |
| 233 | case 0x19: op_mvs(); break; |
| 234 | case 0x1a: op_out(); break; |
| 235 | case 0x1b: op_disn(); break; |
| 236 | |
| 237 | case 0x28: op_szk(); break; |
| 238 | case 0x29: op_szi(); break; |
| 239 | case 0x2a: op_rf1(); break; |
| 240 | case 0x2b: op_sf1(); break; |
| 241 | case 0x2c: op_rf2(); break; |
| 242 | case 0x2d: op_sf2(); break; |
| 243 | case 0x2e: op_tf1(); break; |
| 244 | case 0x2f: op_tf2(); break; |
| 245 | |
| 246 | default: |
| 247 | switch (m_op & 0xfc) |
| 248 | { |
| 249 | case 0x1c: op_szm(); break; |
| 250 | case 0x20: op_stm(); break; |
| 251 | case 0x24: op_rsm(); break; |
| 252 | |
| 253 | case 0x30: op_xci(); break; |
| 254 | case 0x34: op_xcd(); break; |
| 255 | case 0x38: op_xc(); break; |
| 256 | case 0x3c: op_lam(); break; |
| 257 | case 0x40: op_lbz(); break; |
| 258 | case 0x44: op_lbf(); break; |
| 259 | case 0x48: op_lbe(); break; |
| 260 | case 0x4c: op_lbep(); break; |
| 261 | } |
| 262 | break; |
| 263 | |
| 264 | } |
| 265 | break; |
| 266 | } // big switch |
| 267 | } |
| 200 | 268 | } |
trunk/src/emu/cpu/amis2000/amis2000op.inc
| r243252 | r243253 | |
| 1 | 1 | // AMI S2000 opcode handlers |
| 2 | |
| 3 | // internal helpers |
| 4 | |
| 5 | void amis2000_device::op_illegal() |
| 6 | { |
| 7 | logerror("%s unknown opcode $%02X at $%04X\n", tag(), m_op, m_pc); |
| 8 | } |
| 9 | |
| 10 | |
| 11 | // Register Instructions |
| 12 | |
| 13 | void amis2000_device::op_lai() |
| 14 | { |
| 15 | // LAI X: load ACC with X, select I and K inputs |
| 16 | op_illegal(); |
| 17 | } |
| 18 | |
| 19 | void amis2000_device::op_lab() |
| 20 | { |
| 21 | // LAB: load ACC with BL |
| 22 | op_illegal(); |
| 23 | } |
| 24 | |
| 25 | void amis2000_device::op_lae() |
| 26 | { |
| 27 | // LAE: load ACC with E |
| 28 | op_illegal(); |
| 29 | } |
| 30 | |
| 31 | void amis2000_device::op_xab() |
| 32 | { |
| 33 | // XAB: exchange ACC with BL |
| 34 | op_illegal(); |
| 35 | } |
| 36 | |
| 37 | void amis2000_device::op_xabu() |
| 38 | { |
| 39 | // XABU: exchange ACC with BU |
| 40 | op_illegal(); |
| 41 | } |
| 42 | |
| 43 | void amis2000_device::op_xae() |
| 44 | { |
| 45 | // XAE: exchange ACC with E |
| 46 | op_illegal(); |
| 47 | } |
| 48 | |
| 49 | void amis2000_device::op_lbe() |
| 50 | { |
| 51 | // LBE Y: load BU with Y, load BL with E |
| 52 | op_illegal(); |
| 53 | } |
| 54 | |
| 55 | void amis2000_device::op_lbep() |
| 56 | { |
| 57 | // LBEP Y: load BU with Y, load BL with E+1 |
| 58 | op_illegal(); |
| 59 | } |
| 60 | |
| 61 | void amis2000_device::op_lbz() |
| 62 | { |
| 63 | // LBZ Y: load BU with Y, load BL with 0 |
| 64 | op_illegal(); |
| 65 | } |
| 66 | |
| 67 | void amis2000_device::op_lbf() |
| 68 | { |
| 69 | // LBF Y: load BU with Y, load BL with 15 |
| 70 | op_illegal(); |
| 71 | } |
| 72 | |
| 73 | |
| 74 | // RAM Instructions |
| 75 | |
| 76 | void amis2000_device::op_lam() |
| 77 | { |
| 78 | // LAM _Y: load ACC with RAM, xor BU with _Y |
| 79 | op_illegal(); |
| 80 | } |
| 81 | |
| 82 | void amis2000_device::op_xc() |
| 83 | { |
| 84 | // XC _Y: exchange ACC with RAM, xor BU with _Y |
| 85 | op_illegal(); |
| 86 | } |
| 87 | |
| 88 | void amis2000_device::op_xci() |
| 89 | { |
| 90 | // XCI _Y: exchange ACC with RAM, increment BL(skip next on carry), xor BU with _Y |
| 91 | op_illegal(); |
| 92 | } |
| 93 | |
| 94 | void amis2000_device::op_xcd() |
| 95 | { |
| 96 | // XCD _Y: exchange ACC with RAM, decrement BL(skip next on carry), xor BU with _Y |
| 97 | op_illegal(); |
| 98 | } |
| 99 | |
| 100 | void amis2000_device::op_stm() |
| 101 | { |
| 102 | // STM Z: set RAM bit Z |
| 103 | op_illegal(); |
| 104 | } |
| 105 | |
| 106 | void amis2000_device::op_rsm() |
| 107 | { |
| 108 | // RSM Z: reset RAM bit Z |
| 109 | op_illegal(); |
| 110 | } |
| 111 | |
| 112 | |
| 113 | // Input/Output Instructions |
| 114 | |
| 115 | void amis2000_device::op_inp() |
| 116 | { |
| 117 | // INP: input D-pins to ACC and RAM |
| 118 | op_illegal(); |
| 119 | } |
| 120 | |
| 121 | void amis2000_device::op_out() |
| 122 | { |
| 123 | // OUT: pulse output ACC and RAM to D-pins |
| 124 | op_illegal(); |
| 125 | } |
| 126 | |
| 127 | void amis2000_device::op_disb() |
| 128 | { |
| 129 | // DISB: set D-latch to ACC and RAM directly |
| 130 | op_illegal(); |
| 131 | } |
| 132 | |
| 133 | void amis2000_device::op_disn() |
| 134 | { |
| 135 | // DISN: set D-latch to ACC+carry via segment decoder |
| 136 | op_illegal(); |
| 137 | } |
| 138 | |
| 139 | void amis2000_device::op_mvs() |
| 140 | { |
| 141 | // MVS: output master strobe latch to A-pins |
| 142 | op_illegal(); |
| 143 | } |
| 144 | |
| 145 | void amis2000_device::op_psh() |
| 146 | { |
| 147 | // PSH: preset high(BL) master strobe latch |
| 148 | op_illegal(); |
| 149 | } |
| 150 | |
| 151 | void amis2000_device::op_psl() |
| 152 | { |
| 153 | // PSL: preset low(BL) master strobe latch |
| 154 | op_illegal(); |
| 155 | } |
| 156 | |
| 157 | void amis2000_device::op_eur() |
| 158 | { |
| 159 | // EUR: set timer frequency(European) and D-latch polarity |
| 160 | op_illegal(); |
| 161 | } |
| 162 | |
| 163 | |
| 164 | // Program Control Instructions |
| 165 | |
| 166 | void amis2000_device::op_pp() |
| 167 | { |
| 168 | // PP _X: prepare page/bank with _X |
| 169 | op_illegal(); |
| 170 | } |
| 171 | |
| 172 | void amis2000_device::op_jmp() |
| 173 | { |
| 174 | // JMP X: jump to X(+PP) |
| 175 | op_illegal(); |
| 176 | } |
| 177 | |
| 178 | void amis2000_device::op_jms() |
| 179 | { |
| 180 | // JMS X: call to X(+PP) |
| 181 | op_illegal(); |
| 182 | } |
| 183 | |
| 184 | void amis2000_device::op_rt() |
| 185 | { |
| 186 | // RT: return from subroutine |
| 187 | op_illegal(); |
| 188 | } |
| 189 | |
| 190 | void amis2000_device::op_rts() |
| 191 | { |
| 192 | // RTS: return from subroutine and skip next |
| 193 | op_illegal(); |
| 194 | } |
| 195 | |
| 196 | void amis2000_device::op_nop() |
| 197 | { |
| 198 | // NOP: no operation |
| 199 | } |
| 200 | |
| 201 | |
| 202 | // Skip Instructions |
| 203 | |
| 204 | void amis2000_device::op_szc() |
| 205 | { |
| 206 | // SZC: skip next on zero(no) carry |
| 207 | op_illegal(); |
| 208 | } |
| 209 | |
| 210 | void amis2000_device::op_szm() |
| 211 | { |
| 212 | // SZM Z: skip next on zero RAM bit Z |
| 213 | op_illegal(); |
| 214 | } |
| 215 | |
| 216 | void amis2000_device::op_szi() |
| 217 | { |
| 218 | // SZI: skip next on zero I pin(s) |
| 219 | op_illegal(); |
| 220 | } |
| 221 | |
| 222 | void amis2000_device::op_szk() |
| 223 | { |
| 224 | // SZK: skip next on zero K pin(s) |
| 225 | op_illegal(); |
| 226 | } |
| 227 | |
| 228 | void amis2000_device::op_sbe() |
| 229 | { |
| 230 | // SBE: skip next on BL equ E |
| 231 | op_illegal(); |
| 232 | } |
| 233 | |
| 234 | void amis2000_device::op_sam() |
| 235 | { |
| 236 | // SAM: skip next on ACC equ RAM |
| 237 | op_illegal(); |
| 238 | } |
| 239 | |
| 240 | void amis2000_device::op_sos() |
| 241 | { |
| 242 | // SOS: skip next on SF(timer output), clear SF |
| 243 | op_illegal(); |
| 244 | } |
| 245 | |
| 246 | void amis2000_device::op_tf1() |
| 247 | { |
| 248 | // TF1: skip next on flag 1 |
| 249 | op_illegal(); |
| 250 | } |
| 251 | |
| 252 | void amis2000_device::op_tf2() |
| 253 | { |
| 254 | // TF2: skip next on flag 2 |
| 255 | op_illegal(); |
| 256 | } |
| 257 | |
| 258 | |
| 259 | // Arithmetic and Logical Instructions |
| 260 | |
| 261 | void amis2000_device::op_adcs() |
| 262 | { |
| 263 | // ADCS: add RAM to ACC+carry, skip next on no carry |
| 264 | op_illegal(); |
| 265 | } |
| 266 | |
| 267 | void amis2000_device::op_adis() |
| 268 | { |
| 269 | // ADIS X: add X to ACC, skip next on no carry |
| 270 | op_illegal(); |
| 271 | } |
| 272 | |
| 273 | void amis2000_device::op_add() |
| 274 | { |
| 275 | // ADD: add RAM to ACC |
| 276 | op_illegal(); |
| 277 | } |
| 278 | |
| 279 | void amis2000_device::op_and() |
| 280 | { |
| 281 | // AND: and ACC with RAM |
| 282 | op_illegal(); |
| 283 | } |
| 284 | |
| 285 | void amis2000_device::op_xor() |
| 286 | { |
| 287 | // XOR: xor ACC with RAM |
| 288 | op_illegal(); |
| 289 | } |
| 290 | |
| 291 | void amis2000_device::op_stc() |
| 292 | { |
| 293 | // STC: set carry |
| 294 | op_illegal(); |
| 295 | } |
| 296 | |
| 297 | void amis2000_device::op_rsc() |
| 298 | { |
| 299 | // RSC: reset carry |
| 300 | op_illegal(); |
| 301 | } |
| 302 | |
| 303 | void amis2000_device::op_cma() |
| 304 | { |
| 305 | // CMA: complement ACC |
| 306 | op_illegal(); |
| 307 | } |
| 308 | |
| 309 | void amis2000_device::op_sf1() |
| 310 | { |
| 311 | // SF1: set flag 1 |
| 312 | op_illegal(); |
| 313 | } |
| 314 | |
| 315 | void amis2000_device::op_rf1() |
| 316 | { |
| 317 | // RF1: reset flag 1 |
| 318 | op_illegal(); |
| 319 | } |
| 320 | |
| 321 | void amis2000_device::op_sf2() |
| 322 | { |
| 323 | // SF2: set flag 2 |
| 324 | op_illegal(); |
| 325 | } |
| 326 | |
| 327 | void amis2000_device::op_rf2() |
| 328 | { |
| 329 | // RF2: reset flag 2 |
| 330 | op_illegal(); |
| 331 | } |