📄 ide.lst
字号:
516 3 else
517 3 dataTransferLen = 0;
518 3 }
519 2 }//while (dataTransferLen)
520 1
521 1 return(USBS_PASSED);
522 1 }
523
524 static bit ideWriteCommand()
525 {
526 1 WORD savebc;
527 1 BYTE driveStatus;
528 1 WORD sectorcount;
529 1 BYTE i;
530 1
531 1 writePIO8(ATA_DRIVESEL_REG, 0xe0);
532 1 if (waitForBusyBit() == USBS_FAILED)
533 1 {
534 2 // Oddly enough, an error bit is okay here. It means that the LAST command failed, not this one.
535 2 // A new command is required to clear many error conditions.
536 2 }
537 1
538 1 ((BYTE *) &dwLBA)[0] = EP2FIFOBUF[CBW_DATA_START+2];
539 1 ((BYTE *) &dwLBA)[1] = EP2FIFOBUF[CBW_DATA_START+3];
C51 COMPILER V7.10 IDE 05/28/2007 19:12:32 PAGE 10
540 1 ((BYTE *) &dwLBA)[2] = EP2FIFOBUF[CBW_DATA_START+4];
541 1 ((BYTE *) &dwLBA)[3] = EP2FIFOBUF[CBW_DATA_START+5];
542 1
543 1 // relinquish control of the bulk buffer occupied by the CBW
544 1 EP2BCL = 0x80;
545 1
546 1 // If there's no data length, just exit once we've freed the CBW buffer
547 1 if (!dataTransferLen)
548 1 return USBS_PASSED;
549 1
550 1 // Send the command to the drive
551 1 // This loop breaks up the 32 bit length into 8 bits * sectors.
552 1 // For example, a read of 0x10000 turns into 0x80 sectors.
553 1 while (dataTransferLen)
554 1 {
555 2 dwLBAtoLBARegs(); // Stuff the LBA registers
556 2
557 2 // First stuff the length register (number of sectors to write)
558 2 if (dataTransferLenMSW & 0xfffe)
559 2 {
560 3 writePIO8(ATA_SECTOR_COUNT_REG, 0x1); // 1 for ext addr support
561 3 writePIO8(ATA_SECTOR_COUNT_REG, 0x0); // 0 means 256 blocks of 512
562 3 sectorcount = 0x100;
563 3 }
564 2 else
565 2 {
566 3 sectorcount = (dataTransferLenLSW+ATA_SECTOR_SIZE-1)/ATA_SECTOR_SIZE
567 3 + (dataTransferLenMSW & 1) * 0x80;
568 3 writePIO8(ATA_SECTOR_COUNT_REG, 0); // 0 for MSB of ext address
569 3 writePIO8(ATA_SECTOR_COUNT_REG, sectorcount); // divide len into blocks
570 3 }
571 2
572 2 dwLBA += sectorcount;
573 2
574 2 if (udmaMode && !(dataTransferLenLSW & 0x1ff))
575 2 {
576 3 // Execute the write command
577 3 if (bExtAddrSupport)
578 3 writePIO8(ATA_COMMAND_REG, ATA_COMMAND_DMAWRITE_RETRY_EXT);
579 3 else
580 3 writePIO8(ATA_COMMAND_REG, ATA_COMMAND_DMAWRITE_RETRY);
581 3
582 3 if (sectorcount == 0x100)
583 3 writeUDMA((DWORD)0x10000); // 64k Transfers = 128K
584 3 else
585 3 writeUDMA((dataTransferLen+1) >> 1);
586 3
587 3 // Check status to clear interrupt.
588 3 driveStatus = readATAPI_STATUS_REG();
589 3
590 3 if (driveStatus & ATAPI_STATUS_ERROR_BIT)
591 3 {
592 4 driveStatus = readPIO8(ATAPI_ERROR_REG);
593 4 if (driveStatus & ATAPI_ERROR_ICRC_BIT)
594 4 {
595 5 sensePtr = senseCRCError;
596 5 }
597 4 return(USBS_FAILED);
598 4 }
599 3 else
600 3 {
601 4 if (sectorcount == 0x100)
C51 COMPILER V7.10 IDE 05/28/2007 19:12:32 PAGE 11
602 4 dataTransferLenMSW -= 2;
603 4 else
604 4 dataTransferLen = 0;
605 4 }
606 3 }
607 2 else
608 2 {
609 3 // Execute the write command
610 3 if (bExtAddrSupport)
611 3 writePIO8(ATA_COMMAND_REG, ATA_COMMAND_WRITE_10_EXT);
612 3 else
613 3 writePIO8(ATA_COMMAND_REG, ATA_COMMAND_WRITE_10);
614 3
615 3 while (sectorcount--)
616 3 {
617 4 BYTE limit;
618 4
619 4 // Wait for the drive to be non-busy and have either data or an error
620 4 while (1)
621 4 {
622 5 driveStatus = readATAPI_STATUS_REG();
623 5 if ((driveStatus & (ATAPI_STATUS_BUSY_BIT | ATAPI_STATUS_DRQ_BIT)) == ATAPI_STATUS_DRQ_BIT)
624 5 break;
625 5 if (driveStatus & (ATAPI_STATUS_BUSY_BIT | ATAPI_STATUS_ERROR_BIT) == ATAPI_STATUS_ERROR_BI
-T)
626 5 break;
627 5 }
628 4
629 4 // Normal case -- Got a sector. Send it to the drive (in 8 chunks)
630 4 if (wPacketSize == 0x40)
631 4 limit = 8;
632 4 else
633 4 limit = 1;
634 4
635 4 for (i = 0; i < limit; i++)
636 4 {
637 5 while(EP2CS & bmEPEMPTY); // Wait for host to send data
638 5 savebc = (EP2BCH << 8) | EP2BCL;
639 5
640 5 // Terminate xfer on receipt of short packet, otherwise drop
641 5 // into streamlined case
642 5 if (savebc < wPacketSize)
643 5 {
644 6 EP2BCL = 0;
645 6 writePIO16(ATAPI_DATA_REG, savebc+1); // Add 1 to allow odd xfers.
646 6
647 6 dataTransferLen -= savebc + i * wPacketSize;
648 6 goto stopOnShortPacket;
649 6 }
650 5 else
651 5 {
652 6 EP2BCL = 0;
653 6 writePIO16(ATAPI_DATA_REG, wPacketSize);
654 6 }
655 5 }
656 4 dataTransferLen -= ATA_SECTOR_SIZE; // Returned a full sector.
657 4 } // while (sectorcount)
658 3 } // else (if udma)
659 2 } // While (dataTransferLen)
660 1
661 1 stopOnShortPacket:
662 1
C51 COMPILER V7.10 IDE 05/28/2007 19:12:32 PAGE 12
663 1 if (driveStatus & ATAPI_STATUS_ERROR_BIT)
664 1 return(USBS_FAILED);
665 1 else
666 1 return(USBS_PASSED);
667 1 }
668
669
670 // Don't have the ability to sense media (yet)
671 static bit checkForMedia()
672 {
673 1 return(1);
674 1 }
675
676 void dwLBAtoLBARegs() // Stuff the LBA registers
677 {
678 1 writePIO8(ATA_DRIVESEL_REG, 0xe0);
679 1
680 1 if (bExtAddrSupport)
681 1 {
682 2 writePIO8(ATA_LBA_LSB_REG, ((BYTE *) &dwLBA)[0]); // LBA (31:24)
683 2 writePIO8(ATA_LBA_2SB_REG, 0); // LBA (39:32)
684 2 writePIO8(ATA_LBA_MSB_REG, 0); // LBA (47:40)
685 2 }
686 1
687 1 writePIO8(ATA_LBA_LSB_REG, ((BYTE *) &dwLBA)[3]); // LBA (7:0)
688 1 writePIO8(ATA_LBA_2SB_REG, ((BYTE *) &dwLBA)[2]); // LBA (15:8)
689 1 writePIO8(ATA_LBA_MSB_REG, ((BYTE *) &dwLBA)[1]); // LBA (23:16)
690 1
691 1 if (!bExtAddrSupport)
692 1 {
693 2 writePIO8(ATA_DRIVESEL_REG, ((BYTE *) &dwLBA)[0] | 0xe0);
694 2 }
695 1 }
696
697
698
699 /////////////////////////////////////////////////////////////////////////////////
700 #endif // DEVICE_TYPE_IS_IDE
701 /////////////////////////////////////////////////////////////////////////////////
702
C51 COMPILER V7.10 IDE 05/28/2007 19:12:32 PAGE 13
ASSEMBLY LISTING OF GENERATED OBJECT CODE
; FUNCTION Com00AD (BEGIN)
0000 L?0174:
0000 L?0175:
0000 E500 R MOV A,packetLen
0002 90E69C MOV DPTR,#0E69CH
0005 F0 MOVX @DPTR,A
0006 EF MOV A,R7
0007 A3 INC DPTR
0008 F0 MOVX @DPTR,A
0009 L?0176:
0009 FB MOV R3,A
000A AA06 MOV R2,AR6
000C C3 CLR C
000D E500 E MOV A,dataTransferLen+03H
000F 9B SUBB A,R3
0010 L?0177:
0010 F500 E MOV dataTransferLen+03H,A
0012 E500 E MOV A,dataTransferLen+02H
0014 9A SUBB A,R2
0015 L?0178:
0015 F500 E MOV dataTransferLen+02H,A
0017 E500 E MOV A,dataTransferLen+01H
0019 9400 SUBB A,#00H
001B F500 E MOV dataTransferLen+01H,A
001D E500 E MOV A,dataTransferLen
001F 9400 SUBB A,#00H
0021 F500 E MOV dataTransferLen,A
0023 22 RET
0024 L?0179:
0024 L?0180:
0024 90E691 MOV DPTR,#0E691H
0027 7480 MOV A,#080H
0029 F0 MOVX @DPTR,A
002A L?0181:
002A AF00 E MOV R7,dataTransferLen+03H
002C AE00 E MOV R6,dataTransferLen+02H
002E AD00 E MOV R5,dataTransferLen+01H
0030 AC00 E MOV R4,dataTransferLen
0032 EC MOV A,R4
0033 4D ORL A,R5
0034 4E ORL A,R6
0035 4F ORL A,R7
0036 22 RET
0037 L?0182:
0037 L?0183:
0037 2500 R ADD A,cap_hdr_offset
0039 F582 MOV DPL,A
003B E4 CLR A
003C 34FC ADDC A,#0FCH
003E F583 MOV DPH,A
0040 22 RET
0041 L?0184:
0041 L?0185:
0041 90E691 MOV DPTR,#0E691H
0044 7480 MOV A,#080H
0046 F0 MOVX @DPTR,A
0047 22 RET
0048 L?0186:
0048 L?0187:
C51 COMPILER V7.10 IDE 05/28/2007 19:12:32 PAGE 14
0048 750000 R MOV sensePtr,#HIGH senseOk
004B 750000 R MOV sensePtr+01H,#LOW senseOk
004E 22 RET
004F L?0189:
004F AF00 E MOV R7,dataTransferLen+03H
0051 AE00 E MOV R6,dataTransferLen+02H
0053 AD00 E MOV R5,dataTransferLen+01H
0055 AC00 E MOV R4,dataTransferLen
0057 E4 CLR A
0058 7B12 MOV R3,#012H
005A FA MOV R2,A
005B F9 MOV R1,A
005C F8 MOV R0,A
005D C3 CLR C
005E 020000 E LJMP ?C?ULCMP
0061 L?0190:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -