trunk/src/emu/cpu/dsp16/dsp16.c
| r20223 | r20224 | |
| 30 | 30 | |
| 31 | 31 | dsp16_device::dsp16_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 32 | 32 | : cpu_device(mconfig, DSP16, "DSP16", tag, owner, clock), |
| 33 | | m_program_config("program", ENDIANNESS_LITTLE, 16, 16, -1), |
| 34 | | m_data_config("data", ENDIANNESS_LITTLE, 16, 16, -1), |
| 35 | | m_i(0), |
| 36 | | m_pc(0), |
| 37 | | m_pt(0), |
| 38 | | m_pr(0), |
| 39 | | m_pi(0), |
| 40 | | m_j(0), |
| 41 | | m_k(0), |
| 42 | | m_rb(0), |
| 43 | | m_re(0), |
| 44 | | m_r0(0), |
| 45 | | m_r1(0), |
| 46 | | m_r2(0), |
| 47 | | m_r3(0), |
| 48 | | m_x(0), |
| 49 | | m_y(0), |
| 50 | | m_p(0), |
| 51 | | m_a0(0), |
| 52 | | m_a1(0), |
| 53 | | m_auc(0), |
| 54 | | m_psw(0), |
| 55 | | m_c0(0), |
| 56 | | m_c1(0), |
| 57 | | m_c2(0), |
| 58 | | m_sioc(0), |
| 59 | | m_pioc(0), |
| 60 | | m_ppc(0), |
| 61 | | m_cacheStart(CACHE_INVALID), |
| 62 | | m_cacheEnd(CACHE_INVALID), |
| 63 | | m_cacheRedoNextPC(CACHE_INVALID), |
| 64 | | m_cacheIterations(0), |
| 65 | | m_program(NULL), |
| 66 | | m_data(NULL), |
| 67 | | m_direct(NULL), |
| 68 | | m_icount(0) |
| 33 | m_program_config("program", ENDIANNESS_LITTLE, 16, 16, -1), |
| 34 | m_data_config("data", ENDIANNESS_LITTLE, 16, 16, -1), |
| 35 | m_i(0), |
| 36 | m_pc(0), |
| 37 | m_pt(0), |
| 38 | m_pr(0), |
| 39 | m_pi(0), |
| 40 | m_j(0), |
| 41 | m_k(0), |
| 42 | m_rb(0), |
| 43 | m_re(0), |
| 44 | m_r0(0), |
| 45 | m_r1(0), |
| 46 | m_r2(0), |
| 47 | m_r3(0), |
| 48 | m_x(0), |
| 49 | m_y(0), |
| 50 | m_p(0), |
| 51 | m_a0(0), |
| 52 | m_a1(0), |
| 53 | m_auc(0), |
| 54 | m_psw(0), |
| 55 | m_c0(0), |
| 56 | m_c1(0), |
| 57 | m_c2(0), |
| 58 | m_sioc(0), |
| 59 | m_srta(0), |
| 60 | m_pioc(0), |
| 61 | m_ppc(0), |
| 62 | m_cacheStart(CACHE_INVALID), |
| 63 | m_cacheEnd(CACHE_INVALID), |
| 64 | m_cacheRedoNextPC(CACHE_INVALID), |
| 65 | m_cacheIterations(0), |
| 66 | m_program(NULL), |
| 67 | m_data(NULL), |
| 68 | m_direct(NULL), |
| 69 | m_icount(0) |
| 69 | 70 | { |
| 70 | 71 | // Allocate & setup |
| 71 | 72 | } |
| r20223 | r20224 | |
| 106 | 107 | state_add(DSP16_C1, "C1", m_c1); |
| 107 | 108 | state_add(DSP16_C2, "C2", m_c2); |
| 108 | 109 | state_add(DSP16_SIOC, "SIOC", m_sioc).formatstr("%16s"); |
| 110 | state_add(DSP16_SRTA, "SRTA", m_srta); |
| 109 | 111 | state_add(DSP16_PIOC, "PIOC", m_pioc); //.formatstr("%16s"); |
| 110 | 112 | |
| 111 | 113 | // register our state for saving |
| r20223 | r20224 | |
| 133 | 135 | save_item(NAME(m_c1)); |
| 134 | 136 | save_item(NAME(m_c2)); |
| 135 | 137 | save_item(NAME(m_sioc)); |
| 138 | save_item(NAME(m_srta)); |
| 136 | 139 | save_item(NAME(m_pioc)); |
| 137 | 140 | save_item(NAME(m_ppc)); |
| 138 | 141 | save_item(NAME(m_cacheStart)); |
| r20223 | r20224 | |
| 159 | 162 | // Page 7-5 |
| 160 | 163 | m_pc = 0x0000; |
| 161 | 164 | m_sioc = 0x0000; |
| 165 | // SRTA is unaltered by reset |
| 162 | 166 | m_pioc = 0x0008; |
| 163 | 167 | m_rb = 0x0000; |
| 164 | 168 | m_re = 0x0000; |
| r20223 | r20224 | |
| 182 | 186 | const address_space_config *dsp16_device::memory_space_config(address_spacenum spacenum) const |
| 183 | 187 | { |
| 184 | 188 | return (spacenum == AS_PROGRAM) ? &m_program_config : |
| 185 | | (spacenum == AS_DATA) ? &m_data_config : |
| 186 | | NULL; |
| 189 | (spacenum == AS_DATA) ? &m_data_config : |
| 190 | NULL; |
| 187 | 191 | } |
| 188 | 192 | |
| 189 | 193 | |
| r20223 | r20224 | |
| 312 | 316 | do |
| 313 | 317 | { |
| 314 | 318 | // debugging |
| 315 | | m_ppc = m_pc; // copy PC to previous PC |
| 319 | m_ppc = m_pc; // copy PC to previous PC |
| 316 | 320 | debugger_instruction_hook(this, m_pc); |
| 317 | 321 | |
| 318 | 322 | // instruction fetch & execute |
trunk/src/emu/cpu/dsp16/dsp16dis.c
| r20223 | r20224 | |
| 111 | 111 | |
| 112 | 112 | default: return "UNKNOWN"; |
| 113 | 113 | } |
| 114 | | return ""; |
| 114 | return ret; |
| 115 | 115 | } |
| 116 | 116 | |
| 117 | 117 | astring disasmCONField(const UINT8& CON) |
| r20223 | r20224 | |
| 234 | 234 | { |
| 235 | 235 | switch (SI) |
| 236 | 236 | { |
| 237 | | case 0x00: return 0; // Not a software interrupt |
| 238 | | case 0x01: return 1; // Software Interrupt |
| 237 | case 0x00: return 0; // Not a software interrupt |
| 238 | case 0x01: return 1; // Software Interrupt |
| 239 | 239 | } |
| 240 | 240 | return false; |
| 241 | 241 | } |
| r20223 | r20224 | |
| 270 | 270 | { |
| 271 | 271 | // F1 Y=a0[1] | F1 Y=a1[1] |
| 272 | 272 | const UINT8 Y = (op & 0x000f); |
| 273 | const UINT8 X = (op & 0x0010) >> 4; |
| 273 | 274 | const UINT8 S = (op & 0x0200) >> 9; |
| 274 | 275 | const UINT8 D = (op & 0x0400) >> 10; |
| 275 | 276 | const UINT8 F1 = (op & 0x01e0) >> 5; |
| 276 | 277 | astring yString = disasmYField(Y); |
| 277 | 278 | astring fString = disasmF1Field(F1, D, S); |
| 278 | 279 | astring aString = (opcode == 0x1c) ? "a0" : "a1"; |
| 279 | | sprintf(buffer, "%s = %s, %s", yString.cstr(), aString.cstr(), fString.cstr()); |
| 280 | astring xString = (X) ? "" : "l"; |
| 281 | sprintf(buffer, "%s = %s%s, %s", yString.cstr(), aString.cstr(), xString.cstr(), fString.cstr()); |
| 280 | 282 | break; |
| 281 | 283 | } |
| 282 | 284 | case 0x16: |
trunk/src/emu/cpu/dsp16/dsp16ops.c
| r20223 | r20224 | |
| 45 | 45 | } |
| 46 | 46 | |
| 47 | 47 | |
| 48 | bool dsp16_device::conditionTest(const UINT8& CON) |
| 49 | { |
| 50 | switch (CON) |
| 51 | { |
| 52 | case 0x00: return (m_psw & 0x8000); |
| 53 | case 0x01: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false; |
| 54 | case 0x02: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false; |
| 55 | case 0x03: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false; |
| 56 | case 0x04: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false; |
| 57 | case 0x05: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false; |
| 58 | case 0x06: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false; |
| 59 | case 0x07: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false; |
| 60 | case 0x08: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false; |
| 61 | case 0x09: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false; |
| 62 | case 0x0a: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false; |
| 63 | case 0x0b: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false; |
| 64 | case 0x0c: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false; |
| 65 | case 0x0d: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false; |
| 66 | case 0x0e: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false; |
| 67 | case 0x0f: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false; |
| 68 | case 0x10: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false; |
| 69 | case 0x11: printf("UNIMPLEMENTED condition check @ PC 0x%04x\n", m_pc); return false; |
| 70 | default: logerror("Unrecognized condition at PC=0x%04x\n", m_pc); break; |
| 71 | } |
| 72 | return false; |
| 73 | } |
| 74 | |
| 75 | |
| 48 | 76 | void* dsp16_device::registerFromRImmediateField(const UINT8& R) |
| 49 | 77 | { |
| 50 | 78 | switch (R) |
| r20223 | r20224 | |
| 90 | 118 | case 0x16: return (void*)&m_c1; |
| 91 | 119 | case 0x17: return (void*)&m_c2; |
| 92 | 120 | case 0x18: return (void*)&m_sioc; |
| 93 | | //case 0x19: return (void*)&m_srta; |
| 121 | case 0x19: return (void*)&m_srta; |
| 94 | 122 | //case 0x1a: return (void*)&m_sdx; |
| 95 | 123 | //case 0x1b: return (void*)&m_tdms; |
| 96 | 124 | case 0x1c: return (void*)&m_pioc; |
| r20223 | r20224 | |
| 109 | 137 | //UINT64* destinationReg = NULL; |
| 110 | 138 | //switch (D) |
| 111 | 139 | //{ |
| 112 | | // case 0x00: destinationReg = &m_a0; |
| 113 | | // case 0x01: destinationReg = &m_a1; |
| 114 | | // default: break; |
| 140 | // case 0x00: destinationReg = &m_a0; |
| 141 | // case 0x01: destinationReg = &m_a1; |
| 142 | // default: break; |
| 115 | 143 | //} |
| 116 | 144 | |
| 117 | 145 | // Which source is being used? |
| 118 | 146 | //UINT64* sourceReg = NULL; |
| 119 | 147 | //switch (S) |
| 120 | 148 | //{ |
| 121 | | // case 0x00: sourceReg = &m_a0; |
| 122 | | // case 0x01: sourceReg = &m_a1; |
| 123 | | // default: break; |
| 149 | // case 0x00: sourceReg = &m_a0; |
| 150 | // case 0x01: sourceReg = &m_a1; |
| 151 | // default: break; |
| 124 | 152 | //} |
| 125 | | |
| 153 | |
| 126 | 154 | switch (F1) |
| 127 | 155 | { |
| 128 | 156 | case 0x00: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break; |
| r20223 | r20224 | |
| 173 | 201 | case 0x03: opReg = &m_r3; break; |
| 174 | 202 | default: break; |
| 175 | 203 | } |
| 176 | | |
| 204 | |
| 177 | 205 | const UINT8 lower = Y & 0x03; |
| 178 | 206 | switch (lower) |
| 179 | 207 | { |
| r20223 | r20224 | |
| 209 | 237 | } |
| 210 | 238 | case 0x04: case 0x1c: |
| 211 | 239 | { |
| 212 | | // F1 Y=a0[1] | F1 Y=a1[1] |
| 213 | | //const UINT8 Y = (op & 0x000f); |
| 214 | | //const UINT8 S = (op & 0x0200) >> 9; |
| 215 | | //const UINT8 D = (op & 0x0400) >> 10; |
| 216 | | //const UINT8 F1 = (op & 0x01e0) >> 5; |
| 240 | // F1 Y=a0[1] | F1 Y=a1[1] : (page 3-40) |
| 241 | const UINT8 Y = (op & 0x000f); |
| 242 | const UINT8 X = (op & 0x0010) >> 4; |
| 243 | const UINT8 S = (op & 0x0200) >> 9; |
| 244 | const UINT8 D = (op & 0x0400) >> 10; |
| 245 | const UINT8 F1 = (op & 0x01e0) >> 5; |
| 246 | UINT16* destinationReg = (UINT16*)registerFromYFieldUpper(Y); |
| 247 | UINT16 aRegValue = 0x0000; |
| 248 | if (op & 0xc000) |
| 249 | { |
| 250 | aRegValue = (X) ? (m_a0 & 0x0ffff0000) >> 16 : m_a0 & 0x00000ffff; |
| 251 | } |
| 252 | else |
| 253 | { |
| 254 | aRegValue = (X) ? (m_a1 & 0x0ffff0000) >> 16 : m_a1 & 0x00000ffff; |
| 255 | } |
| 256 | data_write(*destinationReg, aRegValue); |
| 257 | executeYFieldPost(Y); |
| 258 | executeF1Field(F1, D, S); |
| 259 | cycles = 2; |
| 260 | pcAdvance = 1; |
| 217 | 261 | break; |
| 218 | 262 | } |
| 219 | 263 | case 0x16: |
| r20223 | r20224 | |
| 259 | 303 | } |
| 260 | 304 | case 0x19: case 0x1b: |
| 261 | 305 | { |
| 262 | | // F1, y = a0|1, x = *pt++[i] |
| 306 | // NEXT! |
| 307 | // F1, y = a0|1, x = *pt++[i] : (page 3-48) |
| 263 | 308 | //const UINT8 Y = (op & 0x000f); |
| 264 | 309 | //const UINT8 X = (op & 0x0010) >> 4; |
| 265 | 310 | //const UINT8 S = (op & 0x0200) >> 9; |
| r20223 | r20224 | |
| 355 | 400 | case 0x13: |
| 356 | 401 | { |
| 357 | 402 | // if|ifc CON F2 |
| 358 | | //const UINT8 CON = (op & 0x001f); |
| 403 | const UINT8 CON = (op & 0x001f); |
| 359 | 404 | //const UINT8 S = (op & 0x0200) >> 9; |
| 360 | 405 | //const UINT8 D = (op & 0x0400) >> 10; |
| 361 | 406 | //const UINT8 F2 = (op & 0x01e0) >> 5; |
| 407 | bool conditionFulfilled = conditionTest(CON); |
| 408 | if (conditionFulfilled) |
| 409 | { |
| 410 | printf("Fulfilled condition not yet implemented @ PC=0x%04x", m_pc); |
| 411 | } |
| 412 | cycles = 1; |
| 413 | pcAdvance = 1; |
| 362 | 414 | break; |
| 363 | 415 | } |
| 364 | 416 | |
| r20223 | r20224 | |
| 387 | 439 | // Format 5: Branch Indirect Group |
| 388 | 440 | case 0x18: |
| 389 | 441 | { |
| 390 | | // goto B |
| 391 | | //const UINT8 B = (op & 0x0700) >> 8; |
| 442 | // goto B : (page 3-21) |
| 443 | const UINT8 B = (op & 0x0700) >> 8; |
| 444 | switch (B) |
| 445 | { |
| 446 | case 0x00: m_pc = m_pr; break; |
| 447 | case 0x01: printf("UNIMPLEMENTED branch instruction @ PC 0x%04x\n", m_pc); break; |
| 448 | case 0x02: printf("UNIMPLEMENTED branch instruction @ PC 0x%04x\n", m_pc); break; |
| 449 | case 0x03: printf("UNIMPLEMENTED branch instruction @ PC 0x%04x\n", m_pc); break; |
| 450 | default: logerror("DSP16: Invalid branch indirect instruction executed at PC=0x%04x\n.", m_pc); break; |
| 451 | } |
| 452 | cycles = 2; |
| 453 | pcAdvance = 0; |
| 392 | 454 | break; |
| 393 | 455 | } |
| 394 | 456 | |
| r20223 | r20224 | |
| 417 | 479 | } |
| 418 | 480 | case 0x0f: |
| 419 | 481 | { |
| 420 | | // R = Y |
| 421 | | //const UINT8 Y = (op & 0x000f); |
| 422 | | //const UINT8 R = (op & 0x03f0) >> 4; |
| 482 | // R = Y : (page 3-32) |
| 483 | const UINT8 Y = (op & 0x000f); |
| 484 | const UINT8 R = (op & 0x03f0) >> 4; |
| 485 | UINT16* sourceReg = (UINT16*)registerFromYFieldUpper(Y); |
| 486 | void* destinationReg = registerFromRTable(R); |
| 487 | writeRegister(destinationReg, data_read(*sourceReg)); |
| 488 | executeYFieldPost(Y); |
| 489 | cycles = 2; |
| 490 | pcAdvance = 1; |
| 423 | 491 | break; |
| 424 | 492 | } |
| 425 | 493 | case 0x0c: |
| r20223 | r20224 | |
| 463 | 531 | const INT8 M = (op & 0x00ff); |
| 464 | 532 | const UINT8 R = (op & 0x0e00) >> 9; |
| 465 | 533 | void* reg = registerFromRImmediateField(R); |
| 466 | | writeRegister(reg, (INT16)M); // Sign extend 8 bit int |
| 534 | writeRegister(reg, (INT16)M); // Sign extend 8 bit int |
| 467 | 535 | cycles = 1; |
| 468 | 536 | pcAdvance = 1; |
| 469 | 537 | break; |
| r20223 | r20224 | |
| 480 | 548 | // Do |
| 481 | 549 | m_cacheStart = m_pc + 1; |
| 482 | 550 | m_cacheEnd = m_pc + NI + 1; |
| 483 | | m_cacheIterations = K-1; // -1 because we check the counter below |
| 551 | m_cacheIterations = K-1; // -1 because we check the counter below |
| 484 | 552 | cycles = 1; |
| 485 | 553 | pcAdvance = 1; |
| 486 | 554 | } |
| 487 | 555 | else |
| 488 | 556 | { |
| 489 | 557 | // Redo |
| 490 | | m_cacheIterations = K-1; // -1 because we check the counter below |
| 558 | m_cacheIterations = K-1; // -1 because we check the counter below |
| 491 | 559 | m_cacheRedoNextPC = m_pc + 1; |
| 492 | 560 | m_pc = m_cacheStart; |
| 493 | 561 | pcAdvance = 0; |