| 489 | } |
| 490 | |
| 491 | bool Sio2::DoState(StateWrapper& sw) |
| 492 | { |
| 493 | if (!sw.DoMarker("Sio2")) |
| 494 | return false; |
| 495 | |
| 496 | sw.Do(&CmdQueue); |
| 497 | sw.Do(&PortCtrl0); |
| 498 | sw.Do(&PortCtrl1); |
| 499 | sw.Do(&dataIn); |
| 500 | sw.Do(&dataOut); |
| 501 | sw.Do(&ctrl); |
| 502 | sw.Do(&CmdStat); |
| 503 | sw.Do(&PortStat); |
| 504 | sw.Do(&FifoStat); |
| 505 | sw.Do(&FifoTxPos); |
| 506 | sw.Do(&FifoRxPos); |
| 507 | sw.Do(&iStat); |
| 508 | sw.Do(&port); |
| 509 | sw.Do(&queueRead); |
| 510 | sw.Do(&queuePosition); |
| 511 | sw.Do(&commandLength); |
| 512 | sw.Do(&processedLength); |
| 513 | sw.Do(&dmaBlockSize); |
| 514 | sw.Do(&queueComplete); |
| 515 | |
| 516 | sw.Do(&g_Sio2FifoIn); |
| 517 | sw.Do(&g_Sio2FifoOut); |
| 518 | |
| 519 | // CRCs for memory cards. |
| 520 | // If the memory card hasn't changed when loading state, we can safely skip ejecting it. |
| 521 | u64 mcdCrcs[SIO::PORTS][SIO::SLOTS]; |
| 522 | if (sw.IsWriting()) |
| 523 | { |
| 524 | for (u32 port = 0; port < SIO::PORTS; port++) |
| 525 | { |
| 526 | for (u32 slot = 0; slot < SIO::SLOTS; slot++) |
| 527 | mcdCrcs[port][slot] = mcds[port][slot].GetChecksum(); |
| 528 | } |
| 529 | } |
| 530 | sw.DoBytes(mcdCrcs, sizeof(mcdCrcs)); |
| 531 | |
| 532 | if (sw.IsReading()) |
| 533 | { |
| 534 | bool ejected = false; |
| 535 | for (u32 port = 0; port < SIO::PORTS && !ejected; port++) |
| 536 | { |
| 537 | for (u32 slot = 0; slot < SIO::SLOTS; slot++) |
| 538 | { |
| 539 | if (mcdCrcs[port][slot] != mcds[port][slot].GetChecksum()) |
| 540 | { |
| 541 | AutoEject::SetAll(); |
| 542 | ejected = true; |
| 543 | break; |
| 544 | } |
| 545 | } |
| 546 | } |
| 547 | } |
| 548 | |