Subversion Repositories NedoOS

Rev

Rev 345 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download

  1.  
  2. SL811
  3. .EP0Control=0
  4. .EP0Address=1
  5. .EP0Status=3
  6. .EP0Counter=4
  7. .CtrlReg=5
  8. .IntEna=6
  9. .IntStatus=13
  10. .cDATASet=14
  11. .cSOFcnt=15
  12. .INT_CLEAR=0xff
  13.         MACRO WRITE_REG _r,_v
  14.         IF _r == 0x00
  15.                 xor a
  16.         ELSE
  17.                 ld a,_r
  18.         ENDIF
  19.         out (c),a              
  20.         IF _r != _v
  21.                 IF _v == 0x00
  22.                         xor a
  23.                 ELSE
  24.                         ld a,_v
  25.                 ENDIF
  26.         ENDIF
  27.         IF _v & 0x80
  28.                 dec b
  29.                 out (c),a
  30.                 inc b
  31.         ELSE
  32.                 out (0xab),a
  33.         ENDIF
  34.         ENDM
  35. .init  
  36. ; 32.       SL11HardReset();
  37.        
  38.         CALL    .SL11HardReset
  39. ; 33.       USBReset();
  40.         CALL    .USBReset
  41. ; 34.           temp=sl811_init_my();
  42.         CALL    .sl811_init_my
  43.         or a
  44.         ld a,1
  45.         ret z
  46. ; 35.           temp=EnumUsbDev();                              // enumerate USB device, assign USB address = #1
  47.         CALL    .EnumUsbDev
  48.         or a
  49.         ld a,1
  50.         ret z
  51. ; 36.           temp=EnumMassDev();
  52.         CALL    .EnumMassDev
  53.         or a
  54.         ret z
  55.         ld a,1
  56.         ret
  57.  
  58. .DBUF
  59.         defs 64
  60. ; 17.   void USBReset(void)  
  61. ; 18.   {
  62. .USBReset:
  63.         PUSH    BC
  64.         PUSH    DE
  65.         PUSH    AF
  66. ; 19.           BYTE tmp;
  67. ; 20.           tmp =  SL811Read(CtrlReg);
  68.         LD      A,.CtrlReg      ;0x05
  69.         LD      BC,0x80ab
  70.         OUT     (C),A
  71.         in a,(0xab)
  72.         LD      HL,0
  73.         ADD     HL,SP
  74.         LD      (HL),a
  75. ; 21.           SL811Write(CtrlReg,0x08);
  76.         WRITE_REG .CtrlReg,0x08
  77. ; 22.           .delayms(100);
  78.         LD      E,6
  79.         CALL    .delayms
  80. ; 23.           SL811Write(CtrlReg,0x18);
  81.         WRITE_REG .CtrlReg, 0x18
  82. ; 24.           .delayms(100);
  83.         LD      E,6
  84.         CALL    .delayms
  85. ; 25.           SL811Write(CtrlReg,0x08);
  86.         WRITE_REG .CtrlReg, 0x08
  87. ; 26.           .delayms(500);
  88.         LD      E,26
  89.         CALL    .delayms
  90. ; 27.           SL811Write(CtrlReg,tmp);
  91.         LD      A,.CtrlReg      ;0x05
  92.         OUT     (C),A
  93.         LD      HL,0
  94.         ADD     HL,SP
  95.         LD      A,(HL)
  96.         dec B
  97.         OUT     (C),A
  98. ; 28.   }  
  99.         POP     HL
  100.         POP     DE
  101.         POP     BC
  102.         RET
  103. ; 29.   BYTE sl811_init_my(void)
  104. ; 30.   {      
  105. .sl811_init_my:
  106.         PUSH    BC
  107.         PUSH    DE
  108. ; 31.                   SL811Write(cSOFcnt, 0xae);  // Set SOF high counter, no change D+/D-SL11Write(CtrlReg, 0x48); // Setup Normal Operation
  109.         LD      A,.cSOFcnt
  110.         LD      BC,0x80ab
  111.         OUT     (C),A
  112.         LD      A,174
  113.         dec     B       ;LD     B,0x7f
  114.         OUT     (C),A
  115.         inc b
  116. ; 32.                   SL811Write(IntEna, 0x63); // USBA/B, Insert/Remove,USBRest/Resume.
  117.         WRITE_REG .IntEna, 0x63
  118. ; 33.                   SL811Write(cSOFcnt, 0xae);  // Set SOF high counter, no change D+/D-SL11Write(CtrlReg, 0x48); // Setup Normal Operation
  119.         WRITE_REG .cSOFcnt, 0xae
  120. ; 34.                   SL811Write(CtrlReg, 0);         // Disable USB transfer operation and SOF
  121.         WRITE_REG .CtrlReg, 0x00
  122. ; 35.                   SL811Write(cSOFcnt, 0xae);      // Set SOF high counter, no change D+/D-SL11Write(CtrlReg, 0x48);
  123.         WRITE_REG .cSOFcnt, 0xae
  124. ; 36.                                                                           // Clear SL811H mode and setup normal operation
  125. ; 37.                   .delayms(20);     // Delay for HW stablize
  126.         LD      E,2
  127.         CALL    .delayms
  128. ; 38.                   SL811Write(CtrlReg, 0);         // Disable USB transfer operation and SOF
  129.         WRITE_REG .CtrlReg, 0
  130. ; 39.                   if(SL811Read(IntStatus)==0x05) return FALSE;
  131.         LD      A,13
  132.         OUT     (C),A
  133.         IN      A,(0xab)
  134.         CP      5
  135.         JR      Z,.lo183
  136. .lo010:
  137. .lo011:
  138. ; 40.                  
  139. ; 41.                   SL811Write(cSOFcnt,0xae);
  140.         WRITE_REG .cSOFcnt,0xae
  141.         call .USBReset
  142. ; 42.                   SL811Write(IntEna,0x00);
  143.         WRITE_REG .IntEna,0x00
  144. ; 43.                   SL811Write(IntStatus,INT_CLEAR);
  145.         WRITE_REG .IntStatus, 0xFF
  146. ; 44.                   .delayms(100);
  147.         LD      E,6
  148.         CALL    .delayms
  149. ; 45.                   if((SL811Read(IntStatus)&0xc0)!=0x80) return FALSE;
  150.         LD      A,13
  151.         OUT     (C),A
  152.         IN      a,(0xab)
  153.         AND     0xc0
  154.         cp 0x80
  155.         jr z,.lo013
  156. .lo012:
  157. .lo183:
  158.         XOR     A
  159. ; 46.                   puts("'Full' Speed is detected!");      // ** Full Speed is detected ** //  
  160.         JR      .lo014
  161. .lo013:
  162. ; 47.                   SL811Write(cSOFcnt,0xae);       // Set up Master & low speed direct and SOF cnt high=0x2e  
  163.         WRITE_REG .cSOFcnt,0xae
  164. ; 48.                   SL811Write(cDATASet,0xe0);      // SOF Counter Low = 0xE0; 1ms interval  
  165.         WRITE_REG .cDATASet,0xe0
  166. ; 49.                   SL811Write(CtrlReg,0x05);       // Setup 48MHz and SOF enable
  167.         WRITE_REG .CtrlReg,0x05
  168. ; 50.                   SL811Write(EP0Status,0x50);     //90);
  169.         WRITE_REG .EP0Status,0x50
  170. ; 51.                   SL811Write(EP0Counter,0x00);
  171.         WRITE_REG .EP0Counter,0x00
  172. ; 52.                   SL811Write(EP0Control,1);       //sDATA0_RD);   //0x23
  173.         WRITE_REG .EP0Control,1
  174. ; 53.                   .delayms(15);
  175.         LD      E,A
  176.         CALL    .delayms
  177. ; 54.                   SL811Write(IntEna,0x61);
  178.         WRITE_REG .IntEna,0x61
  179. ; 55.                   SL811Write(IntStatus,INT_CLEAR);        //0xff
  180.         WRITE_REG .IntStatus, 0xFF
  181. ; 56.                   return TRUE;
  182.         LD      A,1
  183. ; 57.   }
  184. .lo014:
  185.         POP     DE
  186.         POP     BC
  187.         RET
  188. ; 58.   //*****************************************************************************************  
  189. ; 59.   // .usbXfer:  
  190. ; 60.   // successful transfer = return TRUE  
  191. ; 61.   // fail transfer = return FALSE  
  192. ; 62.   //*****************************************************************************************  
  193. ; 63.   unsigned char .usbXfer(void)  
  194. ; 64.   {    
  195. .usbXfer:
  196.         PUSH    BC
  197.         PUSH    DE
  198.         PUSH    IY
  199.         PUSH    IX
  200.         PUSH    AF
  201. ; 65.       unsigned char xferLen, cmd;  
  202. ; 66.       unsigned char result,remainder,dataX=0x10,bufLen,timeout;  
  203. ; 67.       timeout=TIMEOUT_RETRY;
  204. ; 68.           #define data0 EP0_Buf                    // DATA0 buffer address  
  205. ; 69.       #define data1 (EP0_Buf + 64)                        // DATA1 buffer address  
  206. ; 70.       //------------------------------------------------  
  207. ; 71.       // Define data transfer payload  
  208. ; 72.       //------------------------------------------------  
  209. ; 73.       if (.usbstack.wLen >= 64)          // select proper data payload  
  210.         LD      E,16
  211.         LD      HL,0
  212.         ADD     HL,SP
  213.         LD      (HL),6
  214.         LD      HL,(.usbstack+3)
  215.         LD      BC,64
  216.         AND     A
  217.         SBC     HL,BC
  218.         JR      C,.lo016
  219. .lo015:
  220. ; 74.           xferLen = 64;            // limit to wPayload size    
  221.         LD      IXL,64
  222. ; 75.       else                            // else take < payload len  
  223.         JR      .lo017
  224. .lo016:
  225. ; 76.           xferLen = .usbstack.wLen;            //    
  226.         LD      A,(.usbstack+3)
  227.         LD      IXL,A
  228. .lo017:
  229. ; 77.          
  230. ; 78.       // For IN token  
  231. ; 79.       if (.usbstack.pid==PID_IN)               // for current IN tokens  
  232.         LD      A,(.usbstack+2)
  233.         CP      144
  234.         JR      NZ,.lo019
  235. .lo018:
  236. ; 80.           {
  237. ; 81.                   cmd = sDATA0_RD;            // FS/FS on Hub, sync to sof  
  238.         LD      D,35
  239.         JR      .lo025
  240. .lo019:
  241. ; 82.           }  
  242. ; 83.       // For OUT token  
  243. ; 84.       else if(.usbstack.pid==PID_OUT)              // for OUT tokens  
  244.         CP      16
  245.         LD      B,IXL
  246.         JR      NZ,.lo022
  247. .lo021:
  248. ; 85.       {      
  249. ; 86.           if(xferLen)                                 // only when there are    
  250.         INC     B
  251.         DEC     B
  252.         JR      Z,.lo024
  253. .lo023:
  254. ; 87.                   {
  255. ; 88.               SL811BufWrite(data0,.usbstack.buffer,xferLen);   // data to transfer on USB  
  256.         PUSH    DE
  257.         LD      HL,.usbstack+5
  258.         LD      C,(HL)
  259.         INC     HL
  260.         LD      B,(HL)
  261.         PUSH    BC
  262.         LD      C,IXL
  263.         LD      E,16
  264.         CALL    SL811BUFWRITE
  265.         POP     HL
  266.         POP     DE
  267. .lo024:
  268. ; 89.                   }
  269. ; 90.                   cmd = sDATA0_WR;                        // FS/FS on Hub, sync to sof
  270. ; 91.                   .uDev.bData1[.usbstack.endpoint]=(cmd |= .uDev.bData1[.usbstack.endpoint])^0x40;
  271.         LD      BC,(.usbstack+1)
  272.         LD      B,0
  273.         LD      HL,.uDev+1
  274.         ADD     HL,BC
  275.         LD      A,(HL)
  276.         OR      39
  277.         LD      D,A
  278.         XOR     64
  279.         LD      BC,(.usbstack+1)
  280.         LD      B,0
  281.         LD      HL,.uDev+1
  282.         ADD     HL,BC
  283.         LD      (HL),A
  284. ; 92.       }  
  285. ; 93.       //------------------------------------------------  
  286. ; 94.       // For SETUP/OUT token  
  287. ; 95.       //------------------------------------------------  
  288. ; 96.       else                                            // for current SETUP/OUT tokens  
  289.         JR      .lo025
  290. .lo022:
  291. ; 97.       {      
  292. ; 98.           if(xferLen)                                 // only when there are    
  293.         INC     B
  294.         DEC     B
  295.         JR      Z,.lo027
  296. .lo026:
  297. ; 99.           {                                       // data to transfer on USB
  298. ; 100.              SL811BufWrite(data0,&.usbstack.setup.bmRequest,xferLen);
  299.         PUSH    DE
  300.         LD      HL,.usbstack+7
  301.         PUSH    HL
  302.         LD      C,IXL
  303.         LD      E,16
  304.         CALL    SL811BUFWRITE
  305.         POP     HL
  306.         POP     DE
  307. .lo027:
  308. ; 101.          }  
  309. ; 102.                  cmd = sDATA0_WR;                            // FS/FS on Hub, sync to sof  
  310.         LD      D,39
  311. .lo025:
  312. .lo020:
  313. ; 103.      }  
  314. ; 104.      //------------------------------------------------  
  315. ; 105.      // For EP0's IN/OUT token data, start with DATA1  
  316. ; 106.      // Control Endpoint0's status stage.  
  317. ; 107.      // For data endpoint, IN/OUT data, start ????  
  318. ; 108.      //------------------------------------------------  
  319. ; 109.      if (.usbstack.endpoint == 0 && .usbstack.pid != PID_SETUP)    // for Ep0's IN/OUT token  
  320.         LD      A,(.usbstack+1)
  321.         OR      A
  322.         JR      NZ,.lo029
  323.         LD      A,(.usbstack+2)
  324.         CP      208
  325.         JR      Z,.lo029
  326. .lo031:
  327. .lo030:
  328. .lo028:
  329. ; 110.          cmd |= 0x40;                    // always set DATA1  
  330.         SET     6,D
  331. .lo029:
  332. ; 111.      //------------------------------------------------  
  333. ; 112.      // Arming of USB data transfer for the first pkt  
  334. ; 113.      //------------------------------------------------  
  335. ; 114.      SL811Write(EP0Status,((.usbstack.endpoint&0x0F)|.usbstack.pid));  // PID + EP address  
  336.         LD      A,3
  337.         LD      BC,0x80ab
  338.         OUT     (C),A
  339.         ld hl,(.usbstack+1)
  340.         LD      A,l
  341.         AND     15
  342.         OR      H
  343.         dec B
  344.         OUT     (C),A
  345.         inc B
  346. ; 115.      SL811Write(EP0Counter,.usbstack.usbaddr);                    // USB address  
  347.         LD      A,4
  348.         OUT     (C),A
  349.         LD      A,(.usbstack)
  350.         dec B
  351.         OUT     (C),A
  352.         inc B
  353. ; 116.      SL811Write(EP0Address,data0);                   // buffer address, start with "data0"  
  354.         WRITE_REG .EP0Address,16
  355. ; 117.      SL811Write(.ep0XferLen,xferLen);                 // data transfer length  
  356.         LD      A,2
  357.         OUT     (C),A
  358.         LD      A,IXL
  359.         dec B
  360.         OUT     (C),A
  361.         inc B
  362. ; 118.      SL811Write(IntStatus,INT_CLEAR);                // clear interrupt status
  363.         WRITE_REG .IntStatus,.INT_CLEAR
  364. ; 119.      SL811Write(EP0Control,cmd);                     // Enable ARM and USB transfer start here  
  365.         XOR     A
  366.         OUT     (C),A
  367.         dec B
  368.         OUT     (C),D
  369. .lo033:
  370. ; 120.      //------------------------------------------------  
  371. ; 121.      // Main loop for completing a wLen data trasnfer  
  372. ; 122.      //------------------------------------------------  
  373. ; 123.      while(TRUE)  
  374. .lo034:
  375. .lo036:
  376. ; 124.      {      
  377. ; 125.          //---------------Wait for done interrupt------------------  
  378. ; 126.          while(TRUE)                                             // always ensure requested device is  
  379. .lo037:
  380. ; 127.          {                                                       // inserted at all time, then you will  
  381. ; 128.              result = SL811Read(IntStatus);      
  382.         LD      A,13
  383.         LD      BC,0x80ab
  384.         OUT     (C),A
  385.         dec B
  386.         IN      H,(C)
  387.         LD      B,H
  388. ; 129.                                      // wait for interrupt to be done, and    
  389. ; 130.              if(result & (USB_RESET|INSERT_REMOVE))    // proceed to parse result from slave    
  390.         LD      A,H
  391.         AND     96
  392.         JR      Z,.lo039
  393. .lo038:
  394. ; 131.              {                                                   // device.
  395. ; 132.                  return FALSE;                                   // flag true, so that main loop will    
  396.         XOR     A
  397.         JP      .lo079
  398. .lo039:
  399. ; 133.              }else if(result & USB_A_DONE)                                           // know this condition and exit gracefully  
  400.         BIT     0,B
  401.         JR      Z,.lo033
  402. .lo040:
  403. ; 134.                  break;                          // interrupt done !!!  
  404. .lo041:
  405. .lo035:
  406. ; 135.          }  
  407. ; 136.     
  408. ; 137.          SL811Write(IntStatus,INT_CLEAR); // clear interrupt status  
  409.         LD      B,0x80
  410.         WRITE_REG .IntStatus,.INT_CLEAR
  411. ; 138.          result    = SL811Read(EP0Status);                       // read EP0status register  
  412.         LD      A,3
  413.         LD      B,0x80
  414.         OUT     (C),A
  415.         IN      a,(0xab)
  416.         LD      h,a
  417.         LD      IYH,a
  418. ; 139.          remainder = SL811Read(EP0Counter);                      // remainder value in last pkt xfer  
  419.         LD      A,4
  420.         OUT     (C),A
  421.         IN      a,(0xab)
  422.         LD      L,A
  423.         LD      IYL,A
  424. ; 140.     
  425. ; 141.          //-------------------------ACK----------------------------  
  426. ; 142.          if (result & EP0_ACK)                                   // Transmission ACK  
  427.         BIT     0,H
  428.         JP      Z,.lo063
  429. .lo042:
  430. ; 143.          {      
  431. ; 144.     
  432. ; 145.              // SETUP TOKEN  
  433. ; 146.              if(.usbstack.pid == PID_SETUP)                               // do nothing for SETUP/OUT token    
  434.         LD      A,(.usbstack+2)
  435.         CP      208
  436.         JP      Z,.lo032
  437. .lo044:
  438. ; 147.                  break;                                          // exit while(1) immediately    
  439. .lo045:
  440. ; 148.              // OUT TOKEN                  
  441. ; 149.              else if(.usbstack.pid == PID_OUT)  
  442.         CP      16
  443.         JP      Z,.lo032
  444. .lo046:
  445. ; 150.                  break;    
  446. .lo047:
  447. ; 151.              // IN TOKEN  
  448. ; 152.              else if(.usbstack.pid == PID_IN)  
  449.         CP      144
  450.         JP      NZ,.lo063
  451. .lo048:
  452. ; 153.              {                                                   // for IN token only  
  453. ; 154.                  .usbstack.wLen  -= (WORD)xferLen;    // update remainding wLen value  
  454.         LD      HL,.usbstack+3
  455.         LD      C,IXL
  456.         LD      B,0
  457.         LD      A,(HL)
  458.         SUB     C
  459.         LD      (HL),A
  460.         INC     HL
  461.         LD      A,(HL)
  462.         SBC     A,B
  463.         LD      (HL),A
  464. ; 155.                  cmd   ^= 0x40;              // toggle DATA0/DATA1  
  465.         LD      A,D
  466.         XOR     64
  467.         LD      D,A
  468. ; 156.                  dataX ^= 0x40;                // point to next dataX    
  469.         LD      A,E
  470.         XOR     64
  471.         LD      E,A
  472. ; 157.                  //------------------------------------------------    
  473. ; 158.                  // If host requested for more data than the slave    
  474. ; 159.                  // have, and if the slave's data len is a multiple  
  475. ; 160.                  // of its endpoint payload size/last xferLen. Do    
  476. ; 161.                  // not overwrite data in previous buffer.  
  477. ; 162.                  //------------------------------------------------    
  478. ; 163.                  if(remainder==xferLen)          // empty data detected  
  479.         LD      A,IYL
  480.         CP      C
  481.         JR      NZ,.lo051
  482. .lo050:
  483. ; 164.                      bufLen = 0;         // do not overwriten previous data  
  484.         LD      IXH,0
  485. ; 165.                  else                    // reset bufLen to zero  
  486.         JR      .lo052
  487. .lo051:
  488. ; 166.                      bufLen = xferLen;       // update previous buffer length  
  489.         LD      IXH,IXL
  490. .lo052:
  491. ; 167.                     
  492. ; 168.                  //------------------------------------------------    
  493. ; 169.                  // Arm for next data transfer when requested data    
  494. ; 170.                  // length have not reach zero, i.e. wLen!=0, and  
  495. ; 171.                  // last xferlen of data was completed, i.e.  
  496. ; 172.                  // remainder is equal to zero, not a short pkt  
  497. ; 173.                  //------------------------------------------------    
  498. ; 174.                  if(!remainder && .usbstack.wLen)                         // remainder==0 when last xferLen  
  499.         LD      B,IYL
  500.         INC     B
  501.         DEC     B
  502.         JR      NZ,.lo054
  503.         LD      HL,(.usbstack+3)
  504.         LD      A,L
  505.         OR      H
  506.         JR      Z,.lo054
  507. .lo056:
  508. .lo055:
  509. .lo053:
  510. ; 175.                  {                                               // was all completed or wLen!=0  
  511. ; 176.                      xferLen = (BYTE)(.usbstack.wLen>=64) ? 64:.usbstack.wLen;    // get data length required  
  512.         LD      C,64
  513.         SBC     HL,BC
  514.         JR      C,.lo058
  515.         LD      A,C
  516.         JR      .lo059
  517. .lo058:
  518.         LD      A,(.usbstack+3)
  519. .lo059:
  520.         LD      IXL,A
  521. ; 177.                                     
  522. ; 178.                      SL811Write(.ep0XferLen, xferLen);            // select next xfer length  
  523.         LD      A,2
  524.         LD      BC,0x80ab
  525.         OUT     (C),A
  526.         LD      A,IXL
  527.         dec B   ;LD     B,0x7f
  528.         OUT     (C),A
  529.         inc B
  530. ; 179.                      SL811Write(EP0Address, dataX); //addr);               // data buffer addr    
  531.         LD      A,1
  532.         OUT     (C),A
  533.         dec B
  534.         OUT     (C),E
  535.         inc B
  536. ; 180.                      SL811Write(IntStatus,INT_CLEAR);            // is a LS is on Hub.  
  537.         LD      A,13
  538.         OUT     (C),A
  539.         LD      A,255
  540.         dec B
  541.         OUT     (C),A
  542.         inc B
  543. ; 181.                      SL811Write(EP0Control,cmd);                 // Enable USB transfer and re-arm  
  544.         XOR     A
  545.         LD      B,0x80
  546.         OUT     (C),A
  547.         dec B
  548.         LD      B,0x7f
  549.         OUT     (C),D
  550. .lo054:
  551. ; 182.                                  }                    
  552. ; 183.                  //------------------------------------------------  
  553. ; 184.                  // Copy last IN token data pkt from prev transfer  
  554. ; 185.                  // Check if there was data available during the  
  555. ; 186.                  // last data transfer  
  556. ; 187.                  //------------------------------------------------  
  557. ; 188.                  if(bufLen)                                        
  558.         LD      B,IXH
  559.         INC     B
  560.         DEC     B
  561.         JR      Z,.lo061
  562. .lo060:
  563. ; 189.                  {      
  564. ; 190.                      SL811BufRead(dataX^0x40, .usbstack.buffer, bufLen);  
  565.         PUSH    DE
  566.         LD      HL,.usbstack+5
  567.         LD      C,(HL)
  568.         INC     HL
  569.         LD      B,(HL)
  570.         PUSH    BC
  571.         LD      C,IXH
  572.         LD      A,E
  573.         XOR     64
  574.         LD      E,A
  575.         CALL    SL811BUFREAD
  576.         POP     HL
  577.         POP     DE
  578. ; 191.                      .usbstack.buffer += bufLen;                                
  579.         LD      HL,.usbstack+5
  580.         LD      C,IXH
  581.         LD      B,0
  582.         LD      A,(HL)
  583.         ADD     A,C
  584.         LD      (HL),A
  585.         INC     HL
  586.         LD      A,(HL)
  587.         ADC     A,B
  588.         LD      (HL),A
  589. .lo061:
  590. ; 192.                  }  
  591. ; 193.                  //------------------------------------------------  
  592. ; 194.                  // Terminate on short packets, i.e. remainder!=0  
  593. ; 195.                  // a short packet or empty data packet OR when    
  594. ; 196.                  // requested data len have completed, i.e.wLen=0  
  595. ; 197.                  // For a LOWSPEED device, the 1st device descp,  
  596. ; 198.                  // wPayload is default to 64-byte, LS device will  
  597. ; 199.                  // only send back a max of 8-byte device descp,  
  598. ; 200.                  // and host detect this as a short packet, and    
  599. ; 201.                  // terminate with OUT status stage  
  600. ; 202.                  //------------------------------------------------  
  601. ; 203.                  if(remainder || !.usbstack.wLen)  
  602.         LD      B,IYL
  603.         INC     B
  604.         DEC     B
  605.         JR      NZ,.lo032
  606.         LD      HL,(.usbstack+3)
  607.         LD      A,L
  608.         OR      H
  609.         JR      Z,.lo032
  610. .lo064:
  611. .lo065:
  612. .lo062:
  613. ; 204.                      break;  
  614. .lo063:
  615. .lo049:
  616. .lo043:
  617. ; 205.              }// PID IN                            
  618. ; 206.          }  
  619. ; 207.                 
  620. ; 208.          //-------------------------NAK----------------------------  
  621. ; 209.          if (result & EP0_NAK)                                   // NAK Detected  
  622.         LD      B,IYH
  623.         BIT     6,B
  624.         JR      Z,.lo067
  625. .lo066:
  626. ; 210.          {                                                          
  627. ; 211.                  SL811Write(IntStatus,INT_CLEAR);                // clear interrupt status, need to  
  628.         LD      BC,0x80ab
  629.         WRITE_REG .IntStatus,.INT_CLEAR
  630. ; 212.                  SL811Write(EP0Control,cmd);                     // re-arm and request for last cmd, IN token  
  631.         XOR     A
  632.         OUT     (C),A
  633.         dec B
  634.         OUT     (C),D
  635. ; 213.                                  result = 0;                                     // respond to NAK status only  
  636.         LD      IYH,0
  637. .lo067:
  638. ; 214.          }        
  639. ; 215.          //-----------------------TIMEOUT--------------------------  
  640. ; 216.          if (result & EP0_TIMEOUT)                               // TIMEOUT Detected  
  641.         LD      B,IYH
  642.         BIT     2,B
  643.         JR      Z,.lo074
  644. .lo068:
  645. ; 217.          {                                                          
  646. ; 218.              if(.usbstack.endpoint==0)                                        // happens when hub enumeration  
  647.         LD      A,(.usbstack+1)
  648.         OR      A
  649.         JR      NZ,.lo032
  650. .lo070:
  651. ; 219.              {  
  652. ; 220.                  if((--timeout)==0)  
  653.         LD      L,A
  654.         LD      H,A
  655.         ADD     HL,SP
  656.         DEC     (HL)
  657.         OR      (HL)
  658.         JR      Z,.lo032
  659. .lo072:
  660. ; 221.                  {      
  661. ; 222.                      break;                                      // exit on the timeout detected    
  662. .lo073:
  663. ; 223.                  }  
  664. ; 224.                  SL811Write(IntStatus,INT_CLEAR);                // clear interrupt status, need to  
  665.         LD      BC,0x80ab
  666.         WRITE_REG .IntStatus,.INT_CLEAR
  667. ; 225.                  SL811Write(EP0Control,cmd);                     // re-arm and request for last cmd again  
  668.         XOR     A
  669.         OUT     (C),A
  670.         dec B
  671.         OUT     (C),D
  672. ; 226.                          }  
  673. ; 227.              else                                                  
  674. .lo071:
  675. ; 228.              {                                                   // all other data endpoint, data transfer    
  676. ; 229.                  break;                                          // happens when data transfer on a device  
  677. .lo074:
  678. .lo069:
  679. ; 230.              }                                                   // through the hub  
  680. ; 231.          }    
  681. ; 232.          //-----------------------STALL----------------------------  
  682. ; 233.          if (result & EP0_STALL)                                 // STALL detected  
  683.         LD      B,IYH
  684.         BIT     7,B
  685.         JR      Z,.lo076
  686. .lo075:
  687. ; 234.              return TRUE;                                        // for unsupported request.                                                                            
  688.         LD      A,1
  689.         JR      .lo079
  690. .lo076:
  691. ; 235.          //----------------------OVEFLOW---------------------------  
  692. ; 236.          if (result & (EP0_OVERFLOW|EP0_ERROR))                              // OVERFLOW detected  
  693.         LD      A,IYH
  694.         AND     34
  695.         JP      Z,.lo033
  696. .lo077:
  697. ; 237.              break;  
  698. .lo078:
  699. .lo032:
  700. ; 238.          //-----------------------ERROR----------------------------  
  701. ; 239.      }   // end of While(1)  
  702. ; 240.      return result & EP0_ACK;
  703.         LD      A,IYH
  704.         AND     1
  705. ; 241.  }  
  706. .lo079:
  707.         POP     HL
  708.         POP     IX
  709.         POP     IY
  710.         POP     DE
  711.         POP     BC
  712.         RET
  713. ; 242.  //*****************************************************************************************  
  714. ; 243.  // Control Endpoint 0's USB Data Xfer  
  715. ; 244.  // .ep0Xfer, endpoint 0 data transfer  
  716. ; 245.  //*****************************************************************************************  
  717. ; 246.  unsigned char .ep0Xfer(void)  
  718. ; 247.  {  
  719. .ep0Xfer:
  720.         PUSH    DE
  721. ; 248.      .usbstack.endpoint=0;  
  722.         XOR     A
  723.         LD      (.usbstack+1),A
  724. ; 249.      //----------------------------------------------------  
  725. ; 250.      // SETUP token with 8-byte request on endpoint 0  
  726. ; 251.      //----------------------------------------------------  
  727. ; 252.      .usbstack.pid=PID_SETUP;  
  728.         LD      A,208
  729.         LD      (.usbstack+2),A
  730. ; 253.      .usbstack.wLen=8;  
  731.         LD      HL,8
  732.         LD      (.usbstack+3),HL
  733. ; 254.      if (!.usbXfer())
  734.         CALL    .usbXfer
  735.         OR      A
  736.         JR      Z,.lo191
  737. .lo080:
  738. ; 255.          {      
  739. ; 256.                  return FALSE;
  740. ; 257.          }
  741. .lo081:
  742. ; 258.      .usbstack.pid  = PID_IN;  
  743.         LD      A,144
  744.         LD      (.usbstack+2),A
  745. ; 259.      //----------------------------------------------------  
  746. ; 260.      // IN or OUT data stage on endpoint 0      
  747. ; 261.      //----------------------------------------------------  
  748. ; 262.      .usbstack.wLen=.usbstack.setup.wLength;  
  749.         LD      HL,(.usbstack+13)
  750.         LD      (.usbstack+3),HL
  751. ; 263.      if (.usbstack.wLen)                                          // if there are data for transfer  
  752.         LD      A,L
  753.         OR      H
  754.         JR      Z,.lo088
  755. .lo082:
  756. ; 264.      {  
  757. ; 265.          if (.usbstack.setup.bmRequest & 0x80)        // host-to-device : IN token  
  758.         LD      A,(.usbstack+7)
  759.         OR      A
  760.         JP      P,.lo085
  761. .lo084:
  762. ; 266.          {  
  763. ; 267.              .usbstack.pid  = PID_IN;    
  764.         LD      A,144
  765.         LD      (.usbstack+2),A
  766. ; 268.                 
  767. ; 269.              if(!.usbXfer())
  768.         CALL    .usbXfer
  769.         OR      A
  770.         JR      Z,.lo191
  771. .lo086:
  772. ; 270.                          {      
  773. ; 271.                                  return FALSE;
  774. ; 272.                          }
  775. .lo087:
  776. ; 273.              .usbstack.pid  = PID_OUT;  
  777.         LD      A,16
  778.         JR      .lo188
  779. ; 274.          }  
  780. ; 275.          else                                            // device-to-host : OUT token  
  781. .lo085:
  782. ; 276.          {
  783. ; 277.              .usbstack.pid  = PID_OUT;  
  784.         LD      A,16
  785.         LD      (.usbstack+2),A
  786. ; 278.                     
  787. ; 279.              if(!.usbXfer())
  788.         CALL    .usbXfer
  789.         OR      A
  790.         JR      Z,.lo191
  791. .lo089:
  792. ; 280.                          {      
  793. ; 281.                                  return FALSE;
  794. ; 282.                          }
  795. .lo090:
  796. ; 283.              .usbstack.pid  = PID_IN;  
  797.         LD      A,144
  798. .lo188:
  799.         LD      (.usbstack+2),A
  800. .lo088:
  801. .lo083:
  802. ; 284.          }  
  803. ; 285.      }  
  804. ; 286.      .delayms(10);  
  805.         LD      E,1
  806.         CALL    .delayms
  807. ; 287.      //----------------------------------------------------  
  808. ; 288.      // Status stage IN or OUT zero-length data packet  
  809. ; 289.      //----------------------------------------------------  
  810. ; 290.      .usbstack.wLen=0;  
  811.         LD      HL,0
  812.         LD      (.usbstack+3),HL
  813. ; 291.      if(!.usbXfer())
  814.         CALL    .usbXfer
  815.         OR      A
  816.         JR      NZ,.lo092
  817. .lo091:
  818. ; 292.          {      
  819. ; 293.                  return FALSE;
  820. .lo191:
  821.         XOR     A
  822. ; 294.          }
  823.         JR      .lo093
  824. .lo092:
  825. ; 295.      return TRUE;                                              
  826.         LD      A,1
  827. ; 296.  }  
  828. .lo093:
  829.         POP     DE
  830.         RET
  831. ; 297. 
  832. ; 298.  unsigned char .epBulkSend(unsigned char *pBuffer,unsigned int len)  
  833. ; 299.  {
  834. .epBulkSend:
  835.         PUSH    IX
  836.         PUSH    DE
  837.         PUSH    BC
  838.         POP     IX
  839. ; 300.      .usbstack.usbaddr=myusbaddr;  
  840.         LD      A,1
  841.         LD      (.usbstack),A
  842. ; 301.      .usbstack.endpoint=.usbstack.epbulkout;  
  843.         LD      A,(.usbstack+16)
  844.         LD      (.usbstack+1),A
  845. ; 302.      .usbstack.pid=PID_OUT;    
  846.         LD      A,16
  847.         LD      (.usbstack+2),A
  848. ; 303.      .usbstack.wLen=len;  
  849.         LD      (.usbstack+3),BC
  850. ; 304.      .usbstack.buffer=pBuffer;  
  851.         LD      L,E
  852.         LD      H,D
  853.         LD      (.usbstack+5),HL
  854. .lo095:
  855. ; 305.      while(len>0)  
  856.         LD      A,IXL
  857.         OR      IXH
  858.         JR      Z,.lo094
  859. .lo096:
  860. ; 306.      {  
  861. ; 307.          if (len >= 64)  
  862.         LD      BC,64
  863.         PUSH    IX
  864.         POP     HL
  865.         SBC     HL,BC
  866.         JR      C,.lo098
  867. .lo097:
  868. ; 308.              .usbstack.wLen = 64;  
  869.         LD      L,C
  870.         LD      H,B
  871.         JR      .lo193
  872. ; 309.          else                  
  873. .lo098:
  874. ; 310.              .usbstack.wLen = len;
  875.         PUSH    IX
  876.         POP     HL
  877. .lo193:
  878.         LD      (.usbstack+3),HL
  879. .lo099:
  880. ; 311.          disable_interrupt();
  881.         DI
  882. .lo101:
  883. ; 312.          while(!.usbXfer()){
  884.         CALL    .usbXfer
  885.         OR      A
  886.         EI
  887.         JR      Z,.lo103
  888. .lo102:
  889. ; 313.                  enable_interrupt();
  890. ; 314.                  puts(".epBulkSend ERROR");
  891. ; 315.              return FALSE;
  892. ; 316.          }
  893. .lo100:
  894. ; 317.          enable_interrupt();
  895. ; 318.          len-=.usbstack.wLen;  
  896.         LD      BC,(.usbstack+3)
  897.         PUSH    IX
  898.         POP     HL
  899.         AND     A
  900.         SBC     HL,BC
  901.         PUSH    HL
  902.         POP     IX
  903. ; 319.          .usbstack.buffer=.usbstack.buffer+.usbstack.wLen;  
  904.         LD      HL,.usbstack+5
  905.         LD      A,(HL)
  906.         ADD     A,C
  907.         LD      (HL),A
  908.         INC     HL
  909.         LD      A,(HL)
  910.         ADC     A,B
  911.         LD      (HL),A
  912.         JR      .lo095
  913. .lo094:
  914. ; 320.      }  
  915. ; 321.      return TRUE;      
  916.         LD      A,1
  917. ; 322.  }  
  918. .lo103:
  919.         POP     HL
  920.         POP     IX
  921.         RET
  922. ; 323.     
  923. ; 324.  unsigned char .epBulkRcv(unsigned char *pBuffer,unsigned int len)  
  924. ; 325.  {  
  925. .epBulkRcv:
  926.         PUSH    IX
  927.         LD      IX,0
  928.         ADD     IX,SP
  929.         PUSH    BC
  930.         PUSH    DE
  931. ; 326.      .usbstack.usbaddr=myusbaddr;  
  932.         LD      A,1
  933.         LD      (.usbstack),A
  934. ; 327.      .usbstack.endpoint=.usbstack.epbulkin;  
  935.         LD      A,(.usbstack+15)
  936.         LD      (.usbstack+1),A
  937. ; 328.      .usbstack.pid=PID_IN;    
  938.         LD      A,144
  939.         LD      (.usbstack+2),A
  940. ; 329.      .usbstack.wLen=len;  
  941.         LD      (.usbstack+3),BC
  942. ; 330.      .usbstack.buffer=pBuffer;
  943.         LD      (.usbstack+5),DE
  944. ; 331.      if(.usbstack.wLen)  
  945.         LD      A,C
  946.         LD      H,B
  947.         OR      H
  948.         JR      Z,.lo106
  949. .lo104:
  950. ; 332.      {    
  951. ; 333.          disable_interrupt();  
  952.         DI
  953. .lo107:
  954. ; 334.          while(!.usbXfer()){
  955.         CALL    .usbXfer
  956.         OR      A
  957.         EI
  958.         JR      Z,.lo109
  959. .lo108:
  960. ; 335.                  enable_interrupt();
  961. ; 336.              return FALSE;
  962. ; 337.          }
  963. .lo106:
  964. ; 338.          enable_interrupt();    
  965. .lo105:
  966. ; 339.      }  
  967. ; 340.      return TRUE;  
  968.         LD      A,1
  969. ; 341.  }  
  970. .lo109:
  971.         LD      SP,IX
  972.         POP     IX
  973.         RET
  974. ; 342.     
  975. ; 343.  //*****************************************************************************************  
  976. ; 344.  // Set Device Address :    
  977. ; 345.  //*****************************************************************************************  
  978. ; 346.  unsigned char SetAddress(unsigned char addr)  
  979. ; 347.  {  
  980. .SetAddress:
  981.         PUSH    BC
  982.         PUSH    DE
  983. ; 348.      .usbstack.usbaddr=0;  
  984.         XOR     A
  985.         LD      (.usbstack),A
  986. ; 349.      .usbstack.setup.bmRequest=0;  
  987.         LD      (.usbstack+7),A
  988. ; 350.      .usbstack.setup.bRequest=SET_ADDRESS;  
  989.         LD      A,5
  990.         LD      (.usbstack+8),A
  991. ; 351.      .usbstack.setup.wValue=addr;  
  992.         LD      C,E
  993.         LD      B,0
  994.         LD      (.usbstack+9),BC
  995. ; 352.      .usbstack.setup.wIndex=0;  
  996.         LD      L,B
  997.         LD      H,B
  998.         LD      (.usbstack+11),HL
  999. ; 353.      .usbstack.setup.wLength=0;  
  1000.         LD      (.usbstack+13),HL
  1001. ; 354.      return .ep0Xfer();  
  1002.         CALL    .ep0Xfer
  1003. ; 355.  }  
  1004.         POP     HL
  1005.         POP     BC
  1006.         RET
  1007. ; 356..
  1008. ; 357.  //*****************************************************************************************  
  1009. ; 358.  // Set Device Configuration :    
  1010. ; 359.  //*****************************************************************************************  
  1011. ; 360.  unsigned char Set_Configuration(void)  
  1012. ; 361.  {  
  1013. .Set_Configuration:
  1014. ; 362.      .usbstack.setup.bmRequest=0;  
  1015.         XOR     A
  1016.         LD      (.usbstack+7),A
  1017. ; 363.      .usbstack.setup.bRequest=SET_CONFIG;  
  1018.         LD      A,9
  1019.         LD      (.usbstack+8),A
  1020. ; 364.      .usbstack.setup.wIndex=0;  
  1021.         LD      HL,0
  1022.         LD      (.usbstack+11),HL
  1023. ; 365.      .usbstack.setup.wLength=0;  
  1024.         LD      (.usbstack+13),HL
  1025. ; 366.      .usbstack.buffer=NULL;  
  1026.         LD      (.usbstack+5),HL
  1027. ; 367.      return .ep0Xfer();  
  1028.         JP      .ep0Xfer
  1029. ; 368.  }
  1030. ; 369. 
  1031. ; 370.  //*****************************************************************************************  
  1032. ; 371.  // Get Device Descriptor : Device, Configuration, String  
  1033. ; 372.  //*****************************************************************************************  
  1034. ; 373.  unsigned char GetDesc(void)  
  1035. ; 374.  {    
  1036. .GetDesc:
  1037.         PUSH    BC
  1038. ; 375.      .usbstack.setup.bmRequest=0x80;  
  1039.         LD      A,0x80
  1040.         LD      (.usbstack+7),A
  1041. ; 376.      .usbstack.setup.bRequest=GET_DESCRIPTOR;  
  1042.         LD      A,6
  1043.         LD      (.usbstack+8),A
  1044. ; 377.      .usbstack.setup.wValue=.usbstack.setup.wValue<<8;
  1045.         LD      HL,.usbstack+9
  1046.         LD      B,(HL)
  1047.         LD      (HL),0
  1048.         INC     HL
  1049.         LD      (HL),B
  1050. ; 378.      return .ep0Xfer();  
  1051.         CALL    .ep0Xfer
  1052. ; 379.  }  
  1053.         POP     BC
  1054.         RET
  1055. ; 380.     
  1056. ; 381.  //*****************************************************************************************  
  1057. ; 382.  // USB Device Enumeration Process  
  1058. ; 383.  // Support 1 confguration and interface #0 and alternate setting #0 only  
  1059. ; 384.  // Support up to 1 control endpoint + 4 data endpoint only  
  1060. ; 385.  //*****************************************************************************************  
  1061. ; 386.  unsigned char EnumUsbDev(void)  
  1062. ; 387.  {
  1063. .EnumUsbDev:
  1064.         PUSH    BC
  1065.         PUSH    DE
  1066.         PUSH    IX
  1067.         PUSH    AF
  1068.         PUSH    AF
  1069. ; 388.      unsigned char i;                                    // always reset USB transfer address    
  1070. ; 389.      unsigned char uAddr = 0;                            // for enumeration to Address #0  
  1071. ; 390.      unsigned char epLen;
  1072. ; 391. 
  1073. ; 392.      //------------------------------------------------  
  1074. ; 393.      // Reset only Slave device attached directly  
  1075. ; 394.      //------------------------------------------------  
  1076. ; 395.      //.uDev.wPayLoad[0] = 64;  // default 64-byte payload of Endpoint 0, address #0  
  1077. ; 396.      if(myusbaddr == 1)        // bus reset for the device attached to SL811HS only  
  1078. .lo110:
  1079. ; 397.          USBReset();     // that will always have the USB address = 0x01 (for a hub)
  1080.         CALL    .USBReset
  1081. .lo111:
  1082. ; 398.      //------------------------------------------------  
  1083. ; 399.      // Set Slave USB Device Address  
  1084. ; 400.      //------------------------------------------------
  1085. ; 401.      if (!SetAddress(myusbaddr))                       // set to specific USB address  
  1086.         LD      E,1
  1087.         CALL    .SetAddress
  1088.         OR      A
  1089.         JR      Z,.lo198
  1090. .lo112:
  1091. ; 402.          return FALSE;                               //  
  1092. .lo113:
  1093. ; 403.      uAddr = myusbaddr;                                // transfer using this new address  
  1094. ; 404. 
  1095. ; 405.      //------------------------------------------------  
  1096. ; 406.      // Get Slave USB Configuration Descriptors  
  1097. ; 407.      //------------------------------------------------  
  1098. ; 408.      .usbstack.usbaddr=uAddr;  
  1099.         LD      A,1
  1100.         LD      (.usbstack),A
  1101. ; 409.      .usbstack.setup.wValue=CONFIGURATION;  
  1102.         LD      HL,2
  1103.         LD      (.usbstack+9),HL
  1104. ; 410.      .usbstack.setup.wIndex=0;  
  1105.         DEC     HL
  1106.         DEC     HL
  1107.         LD      (.usbstack+11),HL
  1108. ; 411.      .usbstack.setup.wLength=64;  
  1109.         LD      L,64
  1110.         LD      (.usbstack+13),HL
  1111. ; 412.      .usbstack.buffer=.DBUF;      
  1112.         LD      HL,.DBUF
  1113.         LD      (.usbstack+5),HL
  1114. ; 413.      if (!GetDesc())
  1115.         LD      IXH,1
  1116.         CALL    .GetDesc
  1117.         OR      A
  1118.         JR      Z,.lo198
  1119. .lo114:
  1120. ; 414.          return FALSE;        
  1121. .lo115:
  1122. ; 415.      .uDev.bNumOfEPs = (.DBUF[9+4] <= MAX_EP) ? .DBUF[9+4] : MAX_EP;  
  1123.         LD      A,(.DBUF+13)
  1124.         LD      B,A
  1125.         LD      A,5
  1126.         CP      B
  1127.         JR      C,.lo117
  1128.         LD      A,(.DBUF+13)
  1129. .lo117:
  1130.         LD      (.uDev),A
  1131. ; 416.      if(.DBUF[9+5]==8) //mass storage device  
  1132.         LD      A,(.DBUF+14)
  1133.         CP      8
  1134.         JR      NZ,.lo120
  1135. .lo119:
  1136. ; 417.          .bFlags.bits.bMassDevice=TRUE;  
  1137.         LD      A,1
  1138.         LD      (.bFlags),A
  1139. .lo120:
  1140. ; 418.      //------------------------------------------------  
  1141. ; 419.      // Set configuration (except for HUB device)  
  1142. ; 420.      //------------------------------------------------  
  1143. ; 421.      .usbstack.usbaddr=uAddr;  
  1144.         LD      A,IXH
  1145.         LD      (.usbstack),A
  1146. ; 422.      .usbstack.setup.wValue=DEVICE;  
  1147.         LD      HL,1
  1148.         LD      (.usbstack+9),HL
  1149. ; 423.                                          // enumerating a FS/LS non-hub device  
  1150. ; 424.          if (!Set_Configuration())       // connected directly to SL811HS  
  1151.         CALL    .Set_Configuration
  1152.         OR      A
  1153.         JR      NZ,.lo122
  1154. .lo121:
  1155. ; 425.                  return FALSE;  
  1156. .lo198:
  1157.         XOR     A
  1158.         JR      .lo132
  1159. .lo122:
  1160. ; 426. 
  1161. ; 427.      //------------------------------------------------  
  1162. ; 428.      // For each slave endpoints, get its attributes  
  1163. ; 429.      // Excluding endpoint0, only data endpoints  
  1164. ; 430.      //------------------------------------------------  
  1165. ; 431. 
  1166. ; 432.      epLen = 0;  
  1167. ; 433.      for (i=1; i<=.uDev.bNumOfEPs; i++)                // For each data endpoint  
  1168.         LD      E,0
  1169.         LD      IXL,1
  1170. .lo124:
  1171.         LD      A,(.uDev)
  1172.         CP      IXL
  1173.         JR      C,.lo123
  1174. .lo125:
  1175. ; 434.      {
  1176. ; 435.          unsigned char bEPAddr  = .DBUF[9 + 9 + epLen+2];    // Ep address and direction  
  1177.         LD      HL,.DBUF+20
  1178.         LD      C,E
  1179.         LD      B,0
  1180.         ADD     HL,BC
  1181.         LD      D,(HL)
  1182. ; 436.          if(.DBUF[9 + 9 + epLen+3]==0x2)     //bulk transfer  
  1183.         LD      HL,.DBUF+21
  1184.         ADD     HL,BC
  1185.         LD      B,(HL)
  1186.         DEC     B
  1187.         DEC     B
  1188.         JR      NZ,.lo131
  1189. .lo127:
  1190. ; 437.          {
  1191. ; 438.              if(bEPAddr&0x80)
  1192.         BIT     7,D
  1193.         LD      A,D
  1194.         JR      Z,.lo130
  1195. .lo129:
  1196. ; 439.                  .usbstack.epbulkin=bEPAddr;
  1197.         LD      (.usbstack+15),A
  1198. ; 440.              else  
  1199.         JR      .lo131
  1200. .lo130:
  1201. ; 441.                  .usbstack.epbulkout=bEPAddr;
  1202.         LD      (.usbstack+16),A
  1203. .lo131:
  1204. .lo128:
  1205. ; 442.          }          
  1206. ; 443.          .uDev.bData1[i] = 0;                     // init data toggle  
  1207.         LD      HL,.uDev+1
  1208.         LD      C,IXL
  1209.         LD      B,0
  1210.         ADD     HL,BC
  1211.         LD      (HL),B
  1212. ; 444.          epLen += 7;  
  1213.         LD      A,E
  1214.         ADD     A,7
  1215.         LD      E,A
  1216.         INC     IXL
  1217.         JR      .lo124
  1218. .lo123:
  1219. ; 445.          //////////////////////////////  
  1220. ; 446.          //////////////////////////////  
  1221. ; 447.      }
  1222. ; 448.      return TRUE;  
  1223.         LD      A,1
  1224. ; 449.  }
  1225. .lo132:
  1226.         POP     HL
  1227.         POP     HL
  1228.         POP     IX
  1229.         POP     DE
  1230.         POP     BC
  1231.         RET
  1232. ; 450.  unsigned char .outbuf[0x20];  
  1233. ; 451.  ///////////////////////////////////////////////////////////////////////////  
  1234. ; 452.  unsigned char EnumMassDev(void)  
  1235. ; 453.  {  
  1236. .EnumMassDev:
  1237. ; 454.      if(!.SPC_Inquiry())
  1238.         CALL    .SPC_Inquiry
  1239.         OR      A
  1240.         JR      NZ,.lo134
  1241. .lo133:
  1242. ; 455.          return 0x81;//FALSE;  
  1243.         LD      A,1
  1244.         RET
  1245. .lo134:
  1246. ; 456.      if(!SPC_TestUnit())  
  1247.         CALL    .SPC_TestUnit
  1248.         OR      A
  1249.         JR      NZ,.lo136
  1250. .lo135:
  1251. ; 457.          return 0x82;//FALSE;  
  1252.         LD      A,1
  1253.         RET
  1254. .lo136:
  1255. ; 458.      if(!SPC_LockMedia())  
  1256.         CALL    .SPC_LockMedia
  1257.         OR      A
  1258.         JR      NZ,.lo138
  1259. .lo137:
  1260. ; 459.          return 0x83;//FALSE;  
  1261.         LD      A,1
  1262.         RET
  1263. .lo138:
  1264. ; 460.      if(!SPC_RequestSense())  
  1265.         CALL    .SPC_RequestSense
  1266.         OR      A
  1267.         JR      NZ,.lo140
  1268. .lo139:
  1269. ; 461.          return 0x84;//FALSE;  
  1270.         LD      A,1
  1271.         RET
  1272. .lo140:
  1273. ; 462.      if(!SPC_TestUnit())  
  1274.         CALL    .SPC_TestUnit
  1275.         OR      A
  1276.         JR      NZ,.lo142
  1277. .lo141:
  1278. ; 463.          return 0x85;//FALSE;  
  1279.         LD      A,1
  1280.         RET
  1281. .lo142:
  1282. ; 464.      if(!.RBC_ReadCapacity())  
  1283.         CALL    .RBC_ReadCapacity
  1284.         OR      A
  1285.         JR      NZ,.lo144
  1286. .lo143:
  1287. ; 465.          return 0x86;//FALSE;  
  1288.         LD      A,1
  1289.         RET
  1290. .lo144:
  1291. ; 466.     
  1292. ; 467.      ////////////////////////////////////////////////////  
  1293. ; 468.      //DeviceInfo.BPB_BytesPerSec=512; //SectorSize 512  
  1294. ; 469.         
  1295. ; 470.      if(!SPC_RequestSense())  
  1296.         CALL    .SPC_RequestSense
  1297.         OR      A
  1298.         JR      NZ,.lo146
  1299. .lo145:
  1300. ; 471.          return 0x87;//FALSE;  
  1301.         LD      A,1
  1302.         RET
  1303. .lo146:
  1304. ; 472.      if(!SPC_TestUnit())  
  1305.         CALL    .SPC_TestUnit
  1306.         OR      A
  1307.         JR      NZ,.lo148
  1308. .lo147:
  1309. ; 473.          return 0x88;//FALSE;  
  1310.         LD      A,1
  1311.         RET
  1312. .lo148:
  1313. ; 474.      if(!.RBC_ReadCapacity())  
  1314.         CALL    .RBC_ReadCapacity
  1315.         OR      A
  1316.         JR      NZ,.lo150
  1317. .lo149:
  1318. ; 475.          return 0x89;//FALSE;  
  1319.         LD      A,1
  1320.         RET
  1321. .lo150:
  1322. ; 476.      ////////////////////////////////////////////////////  
  1323. ; 477.      //if(!.RBC_Read(0x0,1,.DBUF))  
  1324. ; 478.      //   return 0x8a;//FALSE;  
  1325. ; 479.      //////////////////////////////////
  1326. ; 480. 
  1327. ; 481.      return TRUE;  
  1328.         LD      A,0
  1329. ; 482.  }  
  1330. .lo151:
  1331.         RET
  1332. ; 483. 
  1333. ; 484.  const unsigned char .data00[25]={
  1334. ; 485.          0x55,0x53,0x42,0x43,0x60,0xa6,0x24,0xde,  
  1335. ; 486.          0x24,0x00,0x00,0x00,0x80,0x00,0x06,SPC_CMD_INQUIRY,
  1336. ; 487.          0x00,0x00,0x00,0x24,};
  1337. ; 488.               
  1338. ; 489.  unsigned char .SPC_Inquiry(void)  
  1339. ; 490.  {  
  1340. .SPC_Inquiry:
  1341.         PUSH    BC
  1342.         PUSH    DE
  1343. ; 491.      memcpy(.outbuf,.data00,21);
  1344.         LD      BC,21
  1345.         LD      DE,.outbuf
  1346.         LD      HL,.data00
  1347.         LDIR
  1348. ; 492.      if(!.epBulkSend(.outbuf,0x1f))      
  1349.         CALL    .lo208
  1350.         OR      A
  1351.         JR      Z,.lo201
  1352. .lo152:
  1353. ; 493.          return FALSE;  
  1354. .lo153:
  1355. ; 494.      .delayms(150);  
  1356.         LD      E,8
  1357.         CALL    .delayms
  1358. ; 495.      if(!.epBulkRcv(.DBUF,36))  
  1359.         LD      BC,36
  1360.         LD      DE,.DBUF
  1361.         CALL    .epBulkRcv
  1362.         OR      A
  1363.         JR      Z,.lo201
  1364. .lo154:
  1365. ; 496.          return FALSE;      
  1366. .lo155:
  1367. ; 497.      if(!.epBulkRcv(.outbuf,13))  
  1368.         CALL    .lo210
  1369.         OR      A
  1370.         JR      NZ,.lo157
  1371. .lo156:
  1372. ; 498.          return FALSE;    
  1373. .lo201:
  1374.         XOR     A
  1375.         JR      .lo158
  1376. .lo157:
  1377. ; 499.      return TRUE;      
  1378.         LD      A,1
  1379. ; 500.  }  
  1380. .lo158:
  1381.         POP     DE
  1382.         POP     BC
  1383.         RET
  1384. .lo209:
  1385.         LD      (.outbuf+19),A
  1386. .lo208:
  1387.         LD      C,31
  1388.         LD      DE,.outbuf
  1389.         JP      .epBulkSend
  1390. .lo212:
  1391.         LD      E,1
  1392.         CALL    .delayms
  1393. .lo210:
  1394.         LD      BC,13
  1395. .lo211:
  1396.         LD      DE,.outbuf
  1397.         JP      .epBulkRcv
  1398. ; 501.     
  1399. ; 502.  unsigned char SPC_RequestSense(void)  
  1400. ; 503.  {  
  1401. .SPC_RequestSense:
  1402.         PUSH    BC
  1403.         PUSH    DE
  1404. ; 504.      memcpy(.outbuf,.data00,21);  
  1405.         LD      BC,21
  1406.         LD      DE,.outbuf
  1407.         LD      HL,.data00
  1408.         LDIR
  1409. ; 505.      .outbuf[8]=0x0e;  
  1410.         LD      A,14
  1411.         LD      (.outbuf+8),A
  1412. ; 506.      .outbuf[15]=SPC_CMD_REQUESTSENSE;
  1413.         LD      A,3
  1414.         LD      (.outbuf+15),A
  1415. ; 507.      .outbuf[19]=0x0e;        
  1416.         LD      A,14
  1417. ; 508.      if(!.epBulkSend(.outbuf,0x1f))      
  1418.         CALL    .lo209
  1419.         OR      A
  1420.         JR      Z,.lo203
  1421. .lo159:
  1422. ; 509.          return FALSE;  
  1423. .lo160:
  1424. ; 510.      .delayms(5);  
  1425.         LD      E,1
  1426.         CALL    .delayms
  1427. ; 511.      if(!.epBulkRcv(.outbuf,18))  
  1428.         LD      BC,18
  1429.         CALL    .lo211
  1430.         OR      A
  1431.         JR      Z,.lo203
  1432. .lo161:
  1433. ; 512.          return FALSE;
  1434. .lo162:
  1435. ; 513.      if(!.epBulkRcv(.outbuf,13))  
  1436.         CALL    .lo210
  1437.         OR      A
  1438.         JR      NZ,.lo164
  1439. .lo163:
  1440. ; 514.          return FALSE;    
  1441. .lo203:
  1442.         XOR     A
  1443.         JR      .lo165
  1444. .lo164:
  1445. ; 515.      return TRUE;  
  1446.         LD      A,1
  1447. ; 516.  }  
  1448. .lo165:
  1449.         POP     DE
  1450.         POP     BC
  1451.         RET
  1452. ; 517.     
  1453. ; 518.  unsigned char SPC_TestUnit(void)  
  1454. ; 519.  {  
  1455. .SPC_TestUnit:
  1456.         PUSH    BC
  1457.         PUSH    DE
  1458. ; 520.      memcpy(.outbuf,.data00,21);  
  1459.         LD      BC,21
  1460.         LD      DE,.outbuf
  1461.         LD      HL,.data00
  1462.         LDIR
  1463. ; 521.      ////////////////////////////////      
  1464. ; 522.      .outbuf[8]=0x00;  
  1465.         XOR     A
  1466.         LD      (.outbuf+8),A
  1467. ; 523.      .outbuf[12]=0x00;
  1468.         LD      (.outbuf+12),A
  1469. ; 524.      /////////////////////////////////////      
  1470. ; 525.      .outbuf[15]=SPC_CMD_TESTUNITREADY;  
  1471.         LD      (.outbuf+15),A
  1472. ; 526.      .outbuf[19]=0;  
  1473. ; 527.      //////////////////////////////////////  
  1474. ; 528.      if(!.epBulkSend(.outbuf,0x1f))
  1475.         CALL    .lo209
  1476.         OR      A
  1477.         JR      Z,.lo204
  1478. .lo166:
  1479. ; 529.          return FALSE;
  1480. .lo167:
  1481. ; 530.      .delayms(5);  
  1482. ; 531.      if(!.epBulkRcv(.outbuf,13))
  1483.         CALL    .lo212
  1484.         OR      A
  1485.         JR      NZ,.lo169
  1486. .lo168:
  1487. ; 532.          return FALSE;
  1488. .lo204:
  1489.         XOR     A
  1490.         JR      .lo170
  1491. .lo169:
  1492. ; 533.      return TRUE;  
  1493.         LD      A,1
  1494. ; 534.  }  
  1495. .lo170:
  1496.         POP     DE
  1497.         POP     BC
  1498.         RET
  1499. ; 535.     
  1500. ; 536.  unsigned char SPC_LockMedia(void)  
  1501. ; 537.  {  
  1502. .SPC_LockMedia:
  1503.         PUSH    BC
  1504.         PUSH    DE
  1505. ; 538.      memcpy(.outbuf,.data00,21);      
  1506.         LD      BC,21
  1507.         LD      DE,.outbuf
  1508.         LD      HL,.data00
  1509.         LDIR
  1510. ; 539.      .outbuf[8]=0x00;  
  1511.         XOR     A
  1512.         LD      (.outbuf+8),A
  1513. ; 540.      .outbuf[12]=0x00;
  1514.         LD      (.outbuf+12),A
  1515. ; 541.      .outbuf[14]=5;  
  1516.         LD      A,5
  1517.         LD      (.outbuf+14),A
  1518. ; 542.      ///////////////////////////////////////////  
  1519. ; 543.      .outbuf[15]=SPC_CMD_PRVENTALLOWMEDIUMREMOVAL;  
  1520.         LD      A,30
  1521.         LD      (.outbuf+15),A
  1522. ; 544.      .outbuf[19]=1;  
  1523.         LD      A,1
  1524. ; 545.      ///////////////////////////////////////////  
  1525. ; 546.      if(!.epBulkSend(.outbuf,0x1f))      
  1526.         CALL    .lo209
  1527.         OR      A
  1528.         JR      Z,.lo205
  1529. .lo171:
  1530. ; 547.          return FALSE;  
  1531. .lo172:
  1532. ; 548.      .delayms(5);  
  1533. ; 549.     
  1534. ; 550.      if(!.epBulkRcv(.outbuf,13))  
  1535.         CALL    .lo212
  1536.         OR      A
  1537.         JR      NZ,.lo174
  1538. .lo173:
  1539. ; 551.          return FALSE;  
  1540. .lo205:
  1541.         XOR     A
  1542.         JR      .lo175
  1543. .lo174:
  1544. ; 552.     
  1545. ; 553.  /////////////////////////////  
  1546. ; 554.      return TRUE;  
  1547.         LD      A,1
  1548. ; 555.  }  
  1549. .lo175:
  1550.         POP     DE
  1551.         POP     BC
  1552.         RET
  1553. ; 556.     
  1554. ; 557.  unsigned char .RBC_ReadCapacity(void)  
  1555. ; 558.  {  
  1556. .RBC_ReadCapacity:
  1557.         PUSH    BC
  1558.         PUSH    DE
  1559. ; 559.      memcpy(.outbuf,.data00,25);    
  1560.         LD      BC,25
  1561.         LD      DE,.outbuf
  1562.         LD      HL,.data00
  1563.         LDIR
  1564. ; 560.      .outbuf[8]=0x08;    
  1565.         LD      A,8
  1566.         LD      (.outbuf+8),A
  1567. ; 561.      .outbuf[14]=10;  
  1568.         LD      A,10
  1569.         LD      (.outbuf+14),A
  1570. ; 562.      /////////////////////////////////////  
  1571. ; 563.      .outbuf[15]=RBC_CMD_READCAPACITY;
  1572.         LD      A,37
  1573.         LD      (.outbuf+15),A
  1574. ; 564.      .outbuf[19]=0;
  1575.         XOR     A
  1576. ; 565.      /////////////////////////////////////  
  1577. ; 566.      if(!.epBulkSend(.outbuf,0x1f))      
  1578.         CALL    .lo209
  1579.         OR      A
  1580.         JR      Z,.lo207
  1581. .lo176:
  1582. ; 567.          return FALSE;  
  1583. .lo177:
  1584. ; 568.      .delayms(10);  
  1585.         LD      E,1
  1586.         CALL    .delayms
  1587. ; 569.      if(!.epBulkRcv(.DBUF,8))  
  1588.         LD      BC,8
  1589.         LD      DE,.DBUF
  1590.         CALL    .epBulkRcv
  1591.         OR      A
  1592.         JR      Z,.lo207
  1593. .lo178:
  1594. ; 570.          return FALSE;  
  1595. .lo179:
  1596. ; 571.      if(!.epBulkRcv(.outbuf,13))  
  1597.         CALL    .lo210
  1598.         OR      A
  1599.         JR      NZ,.lo181
  1600. .lo180:
  1601. ; 572.          return FALSE;  
  1602. .lo207:
  1603.         XOR     A
  1604.         JR      .lo182
  1605. .lo181:
  1606. ; 573.      /////////////////////////////  
  1607. ; 574.      return TRUE;  
  1608.         LD      A,1
  1609. ; 575.  }  
  1610. .lo182:
  1611.         POP     DE
  1612.         POP     BC
  1613.         RET
  1614.         ;RSEG   CONST
  1615. .data00:
  1616.         DEFB    'U'
  1617.         DEFB    'S'
  1618.         DEFB    'B'
  1619.         DEFB    'C'
  1620.         DEFB    '`'
  1621.         DEFB    166
  1622.         DEFB    '$'
  1623.         DEFB    222
  1624.         DEFB    '$'
  1625.         DEFB    0
  1626.         DEFB    0
  1627.         DEFB    0
  1628.         DEFB    128
  1629.         DEFB    0
  1630.         DEFB    6
  1631.         DEFB    18
  1632.         DEFB    0
  1633.         DEFB    0
  1634.         DEFB    0
  1635.         DEFB    '$'
  1636.         DEFB    0,0,0,0,0
  1637.         ;RSEG   NO_INIT
  1638. .bFlags:
  1639.         DEFS    1
  1640. .usbstack:
  1641.         DEFS    17
  1642. ;.DBUF:
  1643. ;       DEFS    1024
  1644. .uDev:
  1645.         DEFS    6
  1646.         ;RSEG   UDATA0
  1647. .outbuf:
  1648.         DEFS    32
  1649.        
  1650.        
  1651. .delayms
  1652.         halt
  1653.         dec e
  1654.         jr nz,.delayms
  1655.         ret
  1656.        
  1657.         ;bcde=lba,hl=buf,a'=count
  1658. .RBC_Read
  1659.         push hl
  1660.         ld hl,0xa660
  1661.         ld (.outbuf+4),hl
  1662.         ld hl,0xde24
  1663.         ld (.outbuf+6),hl
  1664.         ld hl,0x0080
  1665.         ld (.outbuf+12),hl
  1666.         ld hl,0x2810    ;RBC_CMD_READ10
  1667.         ld (.outbuf+14),hl
  1668.         call .send_cmd
  1669.         pop de ;buffer
  1670.         ret z
  1671.         call .epBulkRcv
  1672.         jr .RBC_rw_end
  1673. .RBC_Write
  1674.         push hl
  1675.         ld hl,0xd9b4
  1676.         ld (.outbuf+4),hl
  1677.         ld hl,0xc177
  1678.         ld (.outbuf+6),hl
  1679.         ld hl,0x0000
  1680.         ld (.outbuf+12),hl
  1681.         ld hl,0x2a10    ;RBC_CMD_WRITE10
  1682.         ld (.outbuf+14),hl
  1683.         call .send_cmd
  1684.         pop de ;buffer
  1685.         ret z
  1686.         call .epBulkSend
  1687. .RBC_rw_end
  1688.         or a
  1689.         ret z
  1690.         ld de,.outbuf
  1691.         ld bc,13
  1692.         call .epBulkRcv
  1693.         or a
  1694.         ld a,0
  1695.         ret nz
  1696.         ld de,.outbuf
  1697.         ld bc,13
  1698.         call .epBulkRcv
  1699.         xor a
  1700.         ret
  1701.        
  1702. .send_cmd       ;out bc=length
  1703.         ld hl,0x5355
  1704.         ld (.outbuf+0),hl
  1705.         ld hl,0x4342
  1706.         ld (.outbuf+2),hl
  1707.         ld hl,.outbuf+16
  1708.         ld (hl),0
  1709.         inc hl
  1710.         ld (hl),b       ;LBA
  1711.         inc hl
  1712.         ld (hl),c
  1713.         inc hl
  1714.         ld (hl),d
  1715.         inc hl
  1716.         ld (hl),e
  1717.         ex af,af'
  1718.         ld l,a
  1719.         ld h,0
  1720.         ld (.outbuf+23),hl
  1721.         ld b,l          ;count*512
  1722.         sla b
  1723.         ld c,h
  1724.         ld (.outbuf+8),bc       ;(long)bytes length
  1725.         ld l,h
  1726.         ld (.outbuf+10),hl
  1727.         ld (.outbuf+21),hl
  1728.         push bc
  1729.         ld bc,0x82ab
  1730.         in a,(c)
  1731.         and 0xaf                ;хост-мод и сл811 в портах
  1732.         out (c),a      
  1733.         ld de,.outbuf
  1734.         ld bc,31
  1735.         call .epBulkSend
  1736.         pop bc
  1737.         or a
  1738.         ret
  1739.  
  1740.        
  1741. .SL11HardReset
  1742.         push bc
  1743.         ld bc,0x83ab    ;ресет sl811
  1744.         in a,(c)
  1745.         and 0xdf
  1746.         out (c),a
  1747.         ld b,0x82               ;сняли питание с разъёма
  1748.         in a,(c)
  1749.         or 0x40
  1750.         out (c),a
  1751.         ;ld e,2;0xff&(2000+20)/20               ;пару секунд чтоп девайс сдох совсем
  1752.         ;call .delayms
  1753.         ld bc,0x82ab
  1754.         in a,(c)
  1755.         and 0xaf                ;хост-мод и сл811 в портах
  1756.         out (c),a      
  1757.         ld e,2;0xff&(50+20)/20
  1758.         call .delayms
  1759.         ld bc,0x83ab
  1760.         in a,(c)
  1761.         or 0x20
  1762.         out (c),a               ;убрали ресет  
  1763.         pop bc
  1764.         ret
  1765.                
  1766.        
  1767. SL811BUFWRITE  
  1768.         pop af
  1769.         pop hl
  1770.         push hl
  1771.         push af
  1772.         ;HL-buf,E-reg, C-count
  1773.         ld a,c
  1774. .wrloop
  1775.         ld bc,0x80ab
  1776.         out (c),e
  1777.         inc e
  1778.         ld b,a
  1779.         outi
  1780.         ld a,b
  1781.         jp nz,.wrloop
  1782.         ret
  1783.        
  1784. SL811BUFREAD   
  1785.         pop af
  1786.         pop hl
  1787.         push hl
  1788.         push af
  1789.         ;HL-buf,E-reg, C-count
  1790.         ld a,c
  1791. .rdloop
  1792.         ld bc,0x80ab
  1793.         out (c),e
  1794.         inc e
  1795.         ld b,a
  1796.         ini
  1797.         ld a,b
  1798.         jp nz,.rdloop
  1799.         ret