trunk/src/emu/cpu/dsp16/dsp16ops.c
| r20274 | r20275 | |
| 112 | 112 | case 0x10: return (void*)&m_x; |
| 113 | 113 | case 0x11: return (void*)&m_y; |
| 114 | 114 | case 0x12: return (void*)addressYL(); |
| 115 | | case 0x13: return (void*)&m_auc; |
| 115 | case 0x13: return (void*)&m_auc; // zero extended |
| 116 | 116 | case 0x14: return (void*)&m_psw; |
| 117 | | case 0x15: return (void*)&m_c0; |
| 118 | | case 0x16: return (void*)&m_c1; |
| 119 | | case 0x17: return (void*)&m_c2; |
| 117 | case 0x15: return (void*)&m_c0; // sign extended |
| 118 | case 0x16: return (void*)&m_c1; // sign extended |
| 119 | case 0x17: return (void*)&m_c2; // sign extended |
| 120 | 120 | case 0x18: return (void*)&m_sioc; |
| 121 | 121 | case 0x19: return (void*)&m_srta; |
| 122 | | //case 0x1a: return (void*)&m_sdx; |
| 122 | case 0x1a: return (void*)&m_sdx; |
| 123 | 123 | //case 0x1b: return (void*)&m_tdms; |
| 124 | 124 | case 0x1c: return (void*)&m_pioc; |
| 125 | | //case 0x1d: return (void*)&m_pdx0; |
| 126 | | //case 0x1e: return (void*)&m_pdx1; |
| 125 | case 0x1d: return (void*)&m_pdx0; |
| 126 | case 0x1e: return (void*)&m_pdx1; |
| 127 | 127 | |
| 128 | 128 | default: return NULL; |
| 129 | 129 | } |
| r20274 | r20275 | |
| 213 | 213 | } |
| 214 | 214 | |
| 215 | 215 | |
| 216 | void dsp16_device::executeZFieldPartOne(const UINT8& Z, UINT16* rN) |
| 217 | { |
| 218 | const UINT8 lower = Z & 0x03; |
| 219 | switch (lower) |
| 220 | { |
| 221 | case 0x00: /* nop */ break; |
| 222 | case 0x01: (*rN)++; break; |
| 223 | case 0x02: (*rN)--; break; |
| 224 | case 0x03: (*rN) += m_j; break; |
| 225 | } |
| 226 | } |
| 227 | |
| 228 | |
| 229 | void dsp16_device::executeZFieldPartTwo(const UINT8& Z, UINT16* rN) |
| 230 | { |
| 231 | const UINT8 lower = Z & 0x03; |
| 232 | switch (lower) |
| 233 | { |
| 234 | case 0x00: (*rN)++; break; |
| 235 | case 0x01: /* nop */ break; |
| 236 | case 0x02: (*rN) += 2; break; |
| 237 | case 0x03: (*rN) += m_k; break; |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | |
| 216 | 242 | void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance) |
| 217 | 243 | { |
| 218 | 244 | cycles = 1; |
| r20274 | r20275 | |
| 262 | 288 | } |
| 263 | 289 | case 0x16: |
| 264 | 290 | { |
| 265 | | // F1, x = Y |
| 266 | | //const UINT8 Y = (op & 0x000f); |
| 267 | | //const UINT8 S = (op & 0x0200) >> 9; |
| 268 | | //const UINT8 D = (op & 0x0400) >> 10; |
| 269 | | //const UINT8 F1 = (op & 0x01e0) >> 5; |
| 291 | // F1, x = Y : (page 3-42) |
| 292 | const UINT8 Y = (op & 0x000f); |
| 293 | const UINT8 S = (op & 0x0200) >> 9; |
| 294 | const UINT8 D = (op & 0x0400) >> 10; |
| 295 | const UINT8 F1 = (op & 0x01e0) >> 5; |
| 296 | executeF1Field(F1, D, S); |
| 297 | UINT16* sourceReg = (UINT16*)registerFromYFieldUpper(Y); |
| 298 | writeRegister(&m_x, data_read(*sourceReg)); |
| 299 | executeYFieldPost(Y); |
| 300 | cycles = 1; |
| 301 | pcAdvance = 1; |
| 270 | 302 | break; |
| 271 | 303 | } |
| 272 | 304 | case 0x17: |
| r20274 | r20275 | |
| 293 | 325 | } |
| 294 | 326 | case 0x1f: |
| 295 | 327 | { |
| 296 | | // F1, y = Y, x = *pt++[i] |
| 297 | | //const UINT8 Y = (op & 0x000f); |
| 298 | | //const UINT8 X = (op & 0x0010) >> 4; |
| 299 | | //const UINT8 S = (op & 0x0200) >> 9; |
| 300 | | //const UINT8 D = (op & 0x0400) >> 10; |
| 301 | | //const UINT8 F1 = (op & 0x01e0) >> 5; |
| 328 | // F1, y = Y, x = *pt++[i] : (page 3-46) |
| 329 | const UINT8 Y = (op & 0x000f); |
| 330 | const UINT8 X = (op & 0x0010) >> 4; |
| 331 | const UINT8 S = (op & 0x0200) >> 9; |
| 332 | const UINT8 D = (op & 0x0400) >> 10; |
| 333 | const UINT8 F1 = (op & 0x01e0) >> 5; |
| 334 | executeF1Field(F1, D, S); |
| 335 | UINT16* sourceRegR = (UINT16*)registerFromYFieldUpper(Y); |
| 336 | writeRegister(&m_y, data_read(*sourceRegR)); |
| 337 | executeYFieldPost(Y); |
| 338 | writeRegister(&m_x, data_read(m_pt)); |
| 339 | switch (X) |
| 340 | { |
| 341 | case 0x00: m_pt++; break; |
| 342 | case 0x01: m_pt += m_i; break; |
| 343 | } |
| 344 | cycles = 2; // TODO: 1 if cached |
| 345 | pcAdvance = 1; |
| 302 | 346 | break; |
| 303 | 347 | } |
| 304 | 348 | case 0x19: case 0x1b: |
| r20274 | r20275 | |
| 313 | 357 | if (Y != 0x00) printf("Unknown opcode @ PC=0x%04x", m_pc); |
| 314 | 358 | m_y = (useA1) ? (m_a1 & 0xffffffff) : (m_a0 & 0xffffffff); // TODO: What happens to Ax when it goes 32 bit (pc=3f & pc=47)? |
| 315 | 359 | executeF1Field(F1, D, S); |
| 316 | | m_x = data_read(m_pt); // TODO: EXM Pin & internal/external ROM? Research. |
| 360 | writeRegister(&m_x, data_read(m_pt)); // TODO: EXM Pin & internal/external ROM? Research. |
| 317 | 361 | switch (X) |
| 318 | 362 | { |
| 319 | 363 | case 0x00: m_pt++; break; |
| r20274 | r20275 | |
| 375 | 419 | // Format 2: Multiply/ALU Read/Write Group |
| 376 | 420 | case 0x15: |
| 377 | 421 | { |
| 378 | | // F1, Z : y[1] |
| 379 | | //const UINT8 Z = (op & 0x000f); |
| 380 | | //const UINT8 X = (op & 0x0010) >> 4; |
| 381 | | //const UINT8 S = (op & 0x0200) >> 9; |
| 382 | | //const UINT8 D = (op & 0x0400) >> 10; |
| 383 | | //const UINT8 F1 = (op & 0x01e0) >> 5; |
| 422 | // F1, Z : y[1] : (page 3-54) |
| 423 | const UINT8 Z = (op & 0x000f); |
| 424 | const UINT8 X = (op & 0x0010) >> 4; |
| 425 | const UINT8 S = (op & 0x0200) >> 9; |
| 426 | const UINT8 D = (op & 0x0400) >> 10; |
| 427 | const UINT8 F1 = (op & 0x01e0) >> 5; |
| 428 | executeF1Field(F1, D, S); |
| 429 | UINT16 temp = 0x0000; |
| 430 | UINT16* rN = (UINT16*)registerFromYFieldUpper(Z); |
| 431 | switch (X) |
| 432 | { |
| 433 | case 0x00: |
| 434 | temp = m_y & 0x0000ffff; |
| 435 | m_y &= 0xffff0000; |
| 436 | m_y |= data_read(*rN); |
| 437 | executeZFieldPartOne(Z, rN); |
| 438 | data_write(*rN, temp); |
| 439 | executeZFieldPartTwo(Z, rN); |
| 440 | break; |
| 441 | case 0x01: |
| 442 | temp = (m_y & 0xffff0000) >> 16; |
| 443 | m_y &= 0x0000ffff; |
| 444 | m_y |= (data_read(*rN) << 16); |
| 445 | executeZFieldPartOne(Z, rN); |
| 446 | data_write(*rN, temp); |
| 447 | executeZFieldPartTwo(Z, rN); |
| 448 | break; |
| 449 | } |
| 450 | cycles = 2; |
| 451 | pcAdvance = 1; |
| 384 | 452 | break; |
| 385 | 453 | } |
| 386 | 454 | case 0x1d: |
| r20274 | r20275 | |
| 497 | 565 | } |
| 498 | 566 | case 0x08: |
| 499 | 567 | { |
| 500 | | // aT = R |
| 501 | | //const UINT8 R = (op & 0x03f0) >> 4; |
| 502 | | //const UINT8 aT = (op & 0x0400) >> 10; |
| 568 | // aT = R : (page 3-30) |
| 569 | const UINT8 R = (op & 0x03f0) >> 4; |
| 570 | const UINT8 aT = (op & 0x0400) >> 10; |
| 571 | UINT64* destinationReg = NULL; |
| 572 | switch(aT) |
| 573 | { |
| 574 | case 0: destinationReg = &m_a1; break; |
| 575 | case 1: destinationReg = &m_a0; break; |
| 576 | default: break; |
| 577 | } |
| 578 | void* sourceReg = registerFromRTable(R); |
| 579 | *destinationReg &= U64(0x00000ffff); |
| 580 | *destinationReg |= (*(UINT16*)sourceReg) << 16; // TODO: Fix for all registers |
| 581 | if (*(UINT16*)sourceReg & 0x8000) |
| 582 | *destinationReg |= U64(0xf00000000); |
| 583 | // TODO: Special function encoding |
| 584 | cycles = 2; |
| 585 | pcAdvance = 1; |
| 503 | 586 | break; |
| 504 | 587 | } |
| 505 | 588 | case 0x0f: |
| r20274 | r20275 | |
| 573 | 656 | // Do |
| 574 | 657 | m_cacheStart = m_pc + 1; |
| 575 | 658 | m_cacheEnd = m_pc + NI + 1; |
| 576 | | m_cacheIterations = K-1; // -1 because we check the counter below |
| 659 | m_cacheIterations = K-1; // -1 because we check the counter @ the end |
| 577 | 660 | cycles = 1; |
| 578 | 661 | pcAdvance = 1; |
| 579 | 662 | } |
| 580 | 663 | else |
| 581 | 664 | { |
| 582 | 665 | // Redo |
| 583 | | m_cacheIterations = K-1; // -1 because we check the counter below |
| 666 | m_cacheIterations = K-1; // -1 because we check the counter @ the end |
| 584 | 667 | m_cacheRedoNextPC = m_pc + 1; |
| 585 | 668 | m_pc = m_cacheStart; |
| 586 | 669 | pcAdvance = 0; |