?login_element?

Subversion Repositories NedoOS

Rev

Rev 800 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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