| Line 402... |
Line 402... |
| 402 |
""" Flushes the CPU instruction and data cache """
|
402 |
""" Flushes the CPU instruction and data cache """
|
| 403 |
return self.lib.monitorcommand(struct.pack("IIII", 20, 0, 0, 0), "III", (None, None, None))
|
403 |
return self.lib.monitorcommand(struct.pack("IIII", 20, 0, 0, 0), "III", (None, None, None))
|
| 404 |
|
404 |
|
| 405 |
def execimage(self, addr):
|
405 |
def execimage(self, addr):
|
| 406 |
""" Runs the emBIOS app at 'addr' """
|
406 |
""" Runs the emBIOS app at 'addr' """
|
| 407 |
return self.lib.monitorcommand(struct.pack("IIII", 21, addr, 0, 0), "III", ("excecimage", None, None))
|
407 |
return self.lib.monitorcommand(struct.pack("IIII", 21, addr, 0, 0), "III", ("rc", None, None))
|
| 408 |
|
408 |
|
| 409 |
def run(self, app):
|
409 |
def run(self, app):
|
| 410 |
""" Uploads and runs the emBIOS app in the string 'app' """
|
410 |
""" Uploads and runs the emBIOS app in the string 'app' """
|
| 411 |
try:
|
411 |
try:
|
| 412 |
appheader = struct.unpack("<8sIIIIIIIIII", app[:48])
|
412 |
appheader = struct.unpack("<8sIIIIIIIIII", app[:48])
|
| Line 469... |
Line 469... |
| 469 |
|
469 |
|
| 470 |
def ipodnano2g_getnandinfo(self):
|
470 |
def ipodnano2g_getnandinfo(self):
|
| 471 |
""" Target-specific function: ipodnano2g
|
471 |
""" Target-specific function: ipodnano2g
|
| 472 |
Gathers some information about the NAND chip used
|
472 |
Gathers some information about the NAND chip used
|
| 473 |
"""
|
473 |
"""
|
| - |
|
474 |
if self.lib.dev.hwtypeid != 0x47324e49: raise DeviceError("Wrong device for target-specific command.")
|
| 474 |
return self.lib.monitorcommand(struct.pack("IIII", 0xffff0001, 0, 0, 0), "IHHHH", ("type", "pagesperblock", "banks", "userblocks", "blocks"))
|
475 |
return self.lib.monitorcommand(struct.pack("IIII", 0xffff0001, 0, 0, 0), "IHHHH", ("type", "pagesperblock", "banks", "userblocks", "blocks"))
|
| 475 |
|
476 |
|
| 476 |
def ipodnano2g_nandread(self, addr, start, count, doecc, checkempty):
|
477 |
def ipodnano2g_nandread(self, addr, start, count, doecc, checkempty):
|
| 477 |
""" Target-specific function: ipodnano2g
|
478 |
""" Target-specific function: ipodnano2g
|
| 478 |
Reads data from the NAND chip into memory
|
479 |
Reads data from the NAND chip into memory
|
| 479 |
"""
|
480 |
"""
|
| - |
|
481 |
if self.lib.dev.hwtypeid != 0x47324e49: raise DeviceError("Wrong device for target-specific command.")
|
| 480 |
return self.lib.monitorcommand(struct.pack("IIII", 0xffff0002, addr | (0x80000000 if doecc != 0 else 0) | (0x40000000 if checkempty != 0 else 0), start, count), "III", (None, None, None))
|
482 |
return self.lib.monitorcommand(struct.pack("IIII", 0xffff0002, addr | (0x80000000 if doecc != 0 else 0) | (0x40000000 if checkempty != 0 else 0), start, count), "III", (None, None, None))
|
| 481 |
|
483 |
|
| 482 |
def ipodnano2g_nandwrite(self, addr, start, count, doecc):
|
484 |
def ipodnano2g_nandwrite(self, addr, start, count, doecc):
|
| 483 |
""" Target-specific function: ipodnano2g
|
485 |
""" Target-specific function: ipodnano2g
|
| 484 |
Writes data to the NAND chip
|
486 |
Writes data to the NAND chip
|
| 485 |
"""
|
487 |
"""
|
| - |
|
488 |
if self.lib.dev.hwtypeid != 0x47324e49: raise DeviceError("Wrong device for target-specific command.")
|
| 486 |
return self.lib.monitorcommand(struct.pack("IIII", 0xffff0003, addr | (0x80000000 if doecc != 0 else 0), start, count), "III", (None, None, None))
|
489 |
return self.lib.monitorcommand(struct.pack("IIII", 0xffff0003, addr | (0x80000000 if doecc != 0 else 0), start, count), "III", (None, None, None))
|
| 487 |
|
490 |
|
| 488 |
def ipodnano2g_nanderase(self, addr, start, count):
|
491 |
def ipodnano2g_nanderase(self, addr, start, count):
|
| 489 |
""" Target-specific function: ipodnano2g
|
492 |
""" Target-specific function: ipodnano2g
|
| 490 |
Erases blocks on the NAND chip and stores the results to memory
|
493 |
Erases blocks on the NAND chip and stores the results to memory
|
| 491 |
"""
|
494 |
"""
|
| - |
|
495 |
if self.lib.dev.hwtypeid != 0x47324e49: raise DeviceError("Wrong device for target-specific command.")
|
| 492 |
return self.lib.monitorcommand(struct.pack("IIII", 0xffff0004, addr, start, count), "III", (None, None, None))
|
496 |
return self.lib.monitorcommand(struct.pack("IIII", 0xffff0004, addr, start, count), "III", (None, None, None))
|
| 493 |
|
497 |
|
| - |
|
498 |
def ipodclassic_gethddinfo(self):
|
| - |
|
499 |
""" Target-specific function: ipodclassic
|
| - |
|
500 |
Gather information about the hard disk drive
|
| - |
|
501 |
"""
|
| - |
|
502 |
if self.lib.dev.hwtypeid != 0x4c435049: raise DeviceError("Wrong device for target-specific command.")
|
| - |
|
503 |
return self.lib.monitorcommand(struct.pack("IIII", 0xffff0001, 0, 0, 0), "IQQII", ("identifyptr", "totalsectors", "virtualsectors", "bbtptr", "bbtsize"))
|
| - |
|
504 |
|
| - |
|
505 |
def ipodclassic_hddaccess(self, type, sector, count, addr):
|
| - |
|
506 |
""" Target-specific function: ipodclassic
|
| - |
|
507 |
Access the hard disk, type = 0 (read) / 1 (write)
|
| - |
|
508 |
"""
|
| - |
|
509 |
if self.lib.dev.hwtypeid != 0x4c435049: raise DeviceError("Wrong device for target-specific command.")
|
| - |
|
510 |
rc = self.lib.monitorcommand(struct.pack("IIQIIII", 0xffff0002, type, sector, count, addr, 0, 0), "III", ("rc", None, None))
|
| - |
|
511 |
if (rc > 0x80000000):
|
| - |
|
512 |
raise DeviceError("HDD access (type=%d, sector=%d, count=%d, addr=0x%08X) failed with RC 0x%08X" % (type, sector, count, addr, rc))
|
| - |
|
513 |
|
| - |
|
514 |
def ipodclassic_writebbt(self, bbt, tempaddr):
|
| - |
|
515 |
""" Target-specific function: ipodclassic
|
| - |
|
516 |
Write hard drive bad block table
|
| - |
|
517 |
"""
|
| - |
|
518 |
if self.lib.dev.hwtypeid != 0x4c435049: raise DeviceError("Wrong device for target-specific command.")
|
| - |
|
519 |
try:
|
| - |
|
520 |
bbtheader = struct.unpack("<8s2024sQII512I", bbt[:4096])
|
| - |
|
521 |
except struct.error:
|
| - |
|
522 |
raise ArgumentError("The specified file is not an emBIOS hard disk BBT")
|
| - |
|
523 |
if bbtheader[0] != "emBIbbth":
|
| - |
|
524 |
raise ArgumentError("The specified file is not an emBIOS hard disk BBT")
|
| - |
|
525 |
virtualsectors = bbtheader[2]
|
| - |
|
526 |
bbtsectors = bbtheader[3]
|
| - |
|
527 |
self.write(tempaddr, bbt)
|
| - |
|
528 |
sector = 0
|
| - |
|
529 |
count = 1
|
| - |
|
530 |
offset = 0
|
| - |
|
531 |
for i in range(bbtsectors):
|
| - |
|
532 |
if bbtheader[4][i] == sector + count:
|
| - |
|
533 |
count = count + 1
|
| - |
|
534 |
else:
|
| - |
|
535 |
self.ipodclassic_hddaccess(1, sector, count, tempaddr + offset)
|
| - |
|
536 |
offset = offset + count * 4096
|
| - |
|
537 |
sector = bbtheader[4][i]
|
| - |
|
538 |
count = 1
|
| - |
|
539 |
self.ipodclassic_hddaccess(1, sector, count, tempaddr + offset)
|
| - |
|
540 |
|
| - |
|
541 |
def storage_get_info(self):
|
| - |
|
542 |
""" Get information about a storage device """
|
| - |
|
543 |
result = self.lib.monitorcommand(struct.pack("IIII", 27, 0, 0, 0), "IIIIIIII", ("version", None, None, "sectorsize", "numsectors", "vendorptr", "productptr", "revisionptr"))
|
| - |
|
544 |
if result.version != 1:
|
| - |
|
545 |
raise ValueError("Unknown version of storage_info struct: %d" % result.version)
|
| - |
|
546 |
return result
|
| - |
|
547 |
|
| - |
|
548 |
def storage_read_sectors_md(self, volume, sector, count, addr):
|
| - |
|
549 |
""" Read sectors from as storage device """
|
| - |
|
550 |
result = self.lib.monitorcommand(struct.pack("IIQIIII", 28, volume, sector, count, addr, 0, 0), "III", ("rc", None, None, None))
|
| - |
|
551 |
if result.rc > 0x80000000:
|
| - |
|
552 |
raise DeviceError("storage_read_sectors_md(volume=%d, sector=%d, count=%d, addr=0x%08X) failed with RC 0x%08X" % (volume, sector, count, addr, rc))
|
| - |
|
553 |
|
| - |
|
554 |
def storage_write_sectors_md(self, volume, sector, count, addr):
|
| - |
|
555 |
""" Read sectors from as storage device """
|
| - |
|
556 |
result = self.lib.monitorcommand(struct.pack("IIQIIII", 29, volume, sector, count, addr, 0, 0), "III", ("rc", None, None, None))
|
| - |
|
557 |
if result.rc > 0x80000000:
|
| - |
|
558 |
raise DeviceError("storage_read_sectors_md(volume=%d, sector=%d, count=%d, addr=0x%08X) failed with RC 0x%08X" % (volume, sector, count, addr, rc))
|
| - |
|
559 |
|
| - |
|
560 |
def file_open(self, filename, mode):
|
| - |
|
561 |
""" Opens a file and returns the handle """
|
| - |
|
562 |
result = self.lib.monitorcommand(struct.pack("IIII%dsB" % len(filename), 30, mode, 0, 0, filename, 0), "III", ("fd", None, None))
|
| - |
|
563 |
if result.fd > 0x80000000:
|
| - |
|
564 |
raise DeviceError("file_open(filename=\"%s\", mode=0x%X) failed with RC=0x%08X, errno=%d" % (filename, mode, result.fd, self.errno()))
|
| - |
|
565 |
return result.fd
|
| - |
|
566 |
|
| - |
|
567 |
def file_size(self, fd):
|
| - |
|
568 |
""" Gets the size of a file referenced by a handle """
|
| - |
|
569 |
result = self.lib.monitorcommand(struct.pack("IIII", 31, fd, 0, 0), "III", ("size", None, None))
|
| - |
|
570 |
if result.size > 0x80000000:
|
| - |
|
571 |
raise DeviceError("file_size(fd=%d) failed with RC=0x%08X, errno=%d" % (fd, result.size, self.errno()))
|
| - |
|
572 |
return result.size
|
| - |
|
573 |
|
| - |
|
574 |
def file_read(self, fd, addr, size):
|
| - |
|
575 |
""" Reads data from a file referenced by a handle """
|
| - |
|
576 |
result = self.lib.monitorcommand(struct.pack("IIII", 32, fd, addr, size), "III", ("rc", None, None))
|
| - |
|
577 |
if result.rc > 0x80000000:
|
| - |
|
578 |
raise DeviceError("file_read(fd=%d, addr=0x%08X, size=0x%08X) failed with RC=0x%08X, errno=%d" % (fd, addr, size, result.rc, self.errno()))
|
| - |
|
579 |
return result.rc
|
| - |
|
580 |
|
| - |
|
581 |
def file_write(self, fd, addr, size):
|
| - |
|
582 |
""" Writes data from a file referenced by a handle """
|
| - |
|
583 |
result = self.lib.monitorcommand(struct.pack("IIII", 33, fd, addr, size), "III", ("rc", None, None))
|
| - |
|
584 |
if result.rc > 0x80000000:
|
| - |
|
585 |
raise DeviceError("file_write(fd=%d, addr=0x%08X, size=0x%08X) failed with RC=0x%08X, errno=%d" % (fd, addr, size, result.rc, self.errno()))
|
| - |
|
586 |
return result.rc
|
| - |
|
587 |
|
| - |
|
588 |
def file_seek(self, fd, offset, whence):
|
| - |
|
589 |
""" Seeks the file handle to the specified position in the file """
|
| - |
|
590 |
result = self.lib.monitorcommand(struct.pack("IIII", 34, fd, offset, whence), "III", ("rc", None, None))
|
| - |
|
591 |
if result.rc > 0x80000000:
|
| - |
|
592 |
raise DeviceError("file_seek(fd=%d, offset=0x%08X, whence=%d) failed with RC=0x%08X, errno=%d" % (fd, offset, whence, result.rc, self.errno()))
|
| - |
|
593 |
return result.rc
|
| - |
|
594 |
|
| - |
|
595 |
def file_truncate(self, fd, length):
|
| - |
|
596 |
""" Truncates a file referenced by a handle to a specified length """
|
| - |
|
597 |
result = self.lib.monitorcommand(struct.pack("IIII", 35, fd, offset, 0), "III", ("rc", None, None))
|
| - |
|
598 |
if result.rc > 0x80000000:
|
| - |
|
599 |
raise DeviceError("file_truncate(fd=%d, length=0x%08X) failed with RC=0x%08X, errno=%d" % (fd, length, result.rc, self.errno()))
|
| - |
|
600 |
return result.rc
|
| - |
|
601 |
|
| - |
|
602 |
def file_sync(self, fd):
|
| - |
|
603 |
""" Flushes a file handles' buffers """
|
| - |
|
604 |
result = self.lib.monitorcommand(struct.pack("IIII", 36, fd, 0, 0), "III", ("rc", None, None))
|
| - |
|
605 |
if result.rc > 0x80000000:
|
| - |
|
606 |
raise DeviceError("file_sync(fd=%d) failed with RC=0x%08X, errno=%d" % (fd, result.rc, self.errno()))
|
| - |
|
607 |
return result.rc
|
| - |
|
608 |
|
| - |
|
609 |
def file_close(self, fd):
|
| - |
|
610 |
""" Closes a file handle """
|
| - |
|
611 |
result = self.lib.monitorcommand(struct.pack("IIII", 37, fd, 0, 0), "III", ("rc", None, None))
|
| - |
|
612 |
if result.rc > 0x80000000:
|
| - |
|
613 |
raise DeviceError("file_close(fd=%d) failed with RC=0x%08X, errno=%d" % (fd, result.rc, self.errno()))
|
| - |
|
614 |
return result.rc
|
| - |
|
615 |
|
| - |
|
616 |
def file_close_all(self):
|
| - |
|
617 |
""" Closes all file handles opened through the debugger """
|
| - |
|
618 |
result = self.lib.monitorcommand(struct.pack("IIII", 38, 0, 0, 0), "III", ("rc", None, None))
|
| - |
|
619 |
if result.rc > 0x80000000:
|
| - |
|
620 |
raise DeviceError("file_close_all() failed with RC=0x%08X, errno=%d" % (result.rc, self.errno()))
|
| - |
|
621 |
return result.rc
|
| - |
|
622 |
|
| - |
|
623 |
def file_kill_all(self):
|
| - |
|
624 |
""" Kills all file handles (in the whole system) """
|
| - |
|
625 |
result = self.lib.monitorcommand(struct.pack("IIII", 39, 0, 0, 0), "III", ("rc", None, None))
|
| - |
|
626 |
if result.rc > 0x80000000:
|
| - |
|
627 |
raise DeviceError("file_kill_all() failed with RC=0x%08X, errno=%d" % (result.rc, self.errno()))
|
| - |
|
628 |
return result.rc
|
| - |
|
629 |
|
| - |
|
630 |
def file_unlink(self, filename):
|
| - |
|
631 |
""" Removes a file """
|
| - |
|
632 |
result = self.lib.monitorcommand(struct.pack("IIII%dsB" % len(filename), 40, 0, 0, 0, filename, 0), "III", ("rc", None, None))
|
| - |
|
633 |
if result.rc > 0x80000000:
|
| - |
|
634 |
raise DeviceError("file_unlink(filename=\"%s\") failed with RC=0x%08X, errno=%d" % (filename, result.rc, self.errno()))
|
| - |
|
635 |
return result.rc
|
| - |
|
636 |
|
| - |
|
637 |
def file_rename(self, oldname, newname):
|
| - |
|
638 |
""" Renames a file """
|
| - |
|
639 |
result = self.lib.monitorcommand(struct.pack("IIII248s%dsB" % min(247, len(newname)), 41, 0, 0, 0, oldname, newname, 0), "III", ("rc", None, None))
|
| - |
|
640 |
if result.rc > 0x80000000:
|
| - |
|
641 |
raise DeviceError("file_rename(oldname=\"%s\", newname=\"%s\") failed with RC=0x%08X, errno=%d" % (oldname, newname, result.rc, self.errno()))
|
| - |
|
642 |
return result.rc
|
| - |
|
643 |
|
| - |
|
644 |
def dir_open(self, dirname):
|
| - |
|
645 |
""" Opens a directory and returns the handle """
|
| - |
|
646 |
result = self.lib.monitorcommand(struct.pack("IIII%dsB" % len(dirname), 42, 0, 0, 0, dirname, 0), "III", ("handle", None, None))
|
| - |
|
647 |
if result.handle == 0:
|
| - |
|
648 |
raise DeviceError("dir_open(dirname=\"%s\") failed with RC=0x%08X, errno=%d" % (dirname, result.handle, self.errno()))
|
| - |
|
649 |
return result.handle
|
| - |
|
650 |
|
| - |
|
651 |
def dir_read(self, handle):
|
| - |
|
652 |
""" Reads the next entry from a directory """
|
| - |
|
653 |
result = self.lib.monitorcommand(struct.pack("IIII", 43, handle, 0, 0), "III", ("version", "maxpath", "ptr"))
|
| - |
|
654 |
if result.ptr == 0:
|
| - |
|
655 |
raise DeviceError("dir_read(handle=0x%08X) failed with RC=0x%08X, errno=%d" % (handle, result.ptr, self.errno()))
|
| - |
|
656 |
if result.version != 1:
|
| - |
|
657 |
raise ValueError("Unknown version of dirent struct: %d" % result.version)
|
| - |
|
658 |
dirent = self.read(result.ptr, result.maxpath + 16)
|
| - |
|
659 |
ret = Bunch()
|
| - |
|
660 |
(ret.name, ret.attributes, ret.size, ret.startcluster, ret.wrtdate, ret.wrttime) = struct.unpack("%dsIIIHH" % result.maxpath, dirent)
|
| - |
|
661 |
ret.name = ret.name[:ret.name.index('\x00')]
|
| - |
|
662 |
return ret
|
| - |
|
663 |
|
| - |
|
664 |
def dir_close(self, handle):
|
| - |
|
665 |
""" Closes a directory handle """
|
| - |
|
666 |
result = self.lib.monitorcommand(struct.pack("IIII", 44, handle, 0, 0), "III", ("rc", None, None))
|
| - |
|
667 |
if result.rc > 0x80000000:
|
| - |
|
668 |
raise DeviceError("dir_close(handle=0x%08X) failed with RC=0x%08X, errno=%d" % (handle, result.rc, self.errno()))
|
| - |
|
669 |
return result.rc
|
| - |
|
670 |
|
| - |
|
671 |
def dir_close_all(self):
|
| - |
|
672 |
""" Closes all directory handles opened through the debugger """
|
| - |
|
673 |
result = self.lib.monitorcommand(struct.pack("IIII", 45, 0, 0, 0), "III", ("rc", None, None))
|
| - |
|
674 |
if result.rc > 0x80000000:
|
| - |
|
675 |
raise DeviceError("dir_close_all() failed with RC=0x%08X, errno=%d" % (result.rc, self.errno()))
|
| - |
|
676 |
return result.rc
|
| - |
|
677 |
|
| - |
|
678 |
def dir_kill_all(self):
|
| - |
|
679 |
""" Kills all directory handles (in the whole system) """
|
| - |
|
680 |
result = self.lib.monitorcommand(struct.pack("IIII", 46, 0, 0, 0), "III", ("rc", None, None))
|
| - |
|
681 |
if result.rc > 0x80000000:
|
| - |
|
682 |
raise DeviceError("dir_kill_all() failed with RC=0x%08X, errno=%d" % (result.rc, self.errno()))
|
| - |
|
683 |
return result.rc
|
| - |
|
684 |
|
| - |
|
685 |
def dir_create(self, dirname):
|
| - |
|
686 |
""" Creates a directory """
|
| - |
|
687 |
result = self.lib.monitorcommand(struct.pack("IIII%dsB" % len(dirname), 47, 0, 0, 0, dirname, 0), "III", ("rc", None, None))
|
| - |
|
688 |
if result.rc > 0x80000000:
|
| - |
|
689 |
raise DeviceError("dir_create(dirname=\"%s\") failed with RC=0x%08X, errno=%d" % (dirname, result.rc, self.errno()))
|
| - |
|
690 |
return result.rc
|
| - |
|
691 |
|
| - |
|
692 |
def dir_remove(self, dirname):
|
| - |
|
693 |
""" Removes an (empty) directory """
|
| - |
|
694 |
result = self.lib.monitorcommand(struct.pack("IIII%dsB" % len(dirname), 48, 0, 0, 0, dirname, 0), "III", ("rc", None, None))
|
| - |
|
695 |
if result.rc > 0x80000000:
|
| - |
|
696 |
raise DeviceError("dir_remove(dirname=\"%s\") failed with RC=0x%08X, errno=%d" % (dirname, result.rc, self.errno()))
|
| - |
|
697 |
return result.rc
|
| - |
|
698 |
|
| - |
|
699 |
def errno(self):
|
| - |
|
700 |
""" Returns the number of the last error that happened """
|
| - |
|
701 |
result = self.lib.monitorcommand(struct.pack("IIII", 49, 0, 0, 0), "III", ("errno", None, None))
|
| - |
|
702 |
return result.errno
|
| - |
|
703 |
|
| - |
|
704 |
def disk_mount(self, volume):
|
| - |
|
705 |
""" Mounts a volume """
|
| - |
|
706 |
result = self.lib.monitorcommand(struct.pack("IIII", 50, volume, 0, 0), "III", ("rc", None, None))
|
| - |
|
707 |
if result.rc > 0x80000000:
|
| - |
|
708 |
raise DeviceError("disk_mount(volume=%d) failed with RC=0x%08X, errno=%d" % (volume, result.rc, self.errno()))
|
| - |
|
709 |
return result.rc
|
| - |
|
710 |
|
| - |
|
711 |
def disk_unmount(self, volume):
|
| - |
|
712 |
""" Unmounts a volume """
|
| - |
|
713 |
result = self.lib.monitorcommand(struct.pack("IIII", 51, volume, 0, 0), "III", ("rc", None, None))
|
| - |
|
714 |
if result.rc > 0x80000000:
|
| - |
|
715 |
raise DeviceError("disk_unmount(volume=%d) failed with RC=0x%08X, errno=%d" % (volume, result.rc, self.errno()))
|
| - |
|
716 |
return result.rc
|
| - |
|
717 |
|
| 494 |
|
718 |
|
| 495 |
class Lib(object):
|
719 |
class Lib(object):
|
| 496 |
def __init__(self):
|
720 |
def __init__(self):
|
| 497 |
self.idVendor = 0xFFFF
|
721 |
self.idVendor = 0xFFFF
|
| 498 |
self.idProduct = 0xE000
|
722 |
self.idProduct = 0xE000
|
| Line 653... |
Line 877... |
| 653 |
sys.stdout.write("Reading data back from device...\n")
|
877 |
sys.stdout.write("Reading data back from device...\n")
|
| 654 |
readdata = embios.read(memaddr, len(datastr))
|
878 |
readdata = embios.read(memaddr, len(datastr))
|
| 655 |
if readdata == datastr:
|
879 |
if readdata == datastr:
|
| 656 |
sys.stdout.write("Data matches!")
|
880 |
sys.stdout.write("Data matches!")
|
| 657 |
else:
|
881 |
else:
|
| 658 |
sys.stdout.write("Data does NOT match. Something got wrong")
|
- |
|
| 659 |
|
882 |
sys.stdout.write("Data does NOT match. Something went wrong")
|
| - |
|
883 |
|
| 660 |
|
884 |
|