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