home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ddkx86v5.zip / DDKX86 / SRC / DEV / DASD / IBM / IBM2SCSI / IO.ASM < prev    next >
Encoding:
Assembly Source File  |  1995-04-14  |  11.1 KB  |  403 lines

  1. ;*DDK*************************************************************************/
  2. ;
  3. ; COPYRIGHT    Copyright (C) 1995 IBM Corporation
  4. ;
  5. ;    The following IBM OS/2 WARP source code is provided to you solely for
  6. ;    the purpose of assisting you in your development of OS/2 WARP device
  7. ;    drivers. You may use this code in accordance with the IBM License
  8. ;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
  9. ;    Copyright statement may not be removed.;
  10. ;*****************************************************************************/
  11.  
  12. ;/************************************************************************/
  13. ;/*                                     */
  14. ;/* Driver Name: IBM2SCSI.ADD - Adapter Driver for ABIOS SCB Devices     */
  15. ;/*         ---------------------------------------------------     */
  16. ;/*                                     */
  17. ;/* Source File Name: IO.ASM                         */
  18. ;/*                                     */
  19. ;/* Descriptive Name: I/O routines for accessing the adpaters.         */
  20. ;/*                                     */
  21. ;/* Function:                                 */
  22. ;/*                                     */
  23. ;/*                                     */
  24. ;/*----------------------------------------------------------------------*/
  25. ;/*                                     */
  26. ;/*                                     */
  27. ;/* DISCLAIMER OF WARRANTIES.  The following [enclosed] code is      */
  28. ;/* provided to you solely for the purpose of assisting you in         */
  29. ;/* the development of your applications. The code is provided         */
  30. ;/* "AS IS", without warranty of any kind. IBM shall not be liable       */
  31. ;/* for any damages arising out of your use of this code, even if     */
  32. ;/* they have been advised of the possibility of such damages.         */
  33. ;/*                                     */
  34. ;/*----------------------------------------------------------------------*/
  35. ;/*                                     */
  36. ;/* Change Log                                 */
  37. ;/*                                     */
  38. ;/* Mark    Date      Programmer  Comment                 */
  39. ;/* ----    ----      ----------  -------                 */
  40. ;/* @nnnn   mm/dd/yy  NNN                         */
  41. ;/*                                     */
  42. ;/*                                     */
  43. ;/************************************************************************/
  44.  
  45. ;
  46. ; Some local equates
  47.  
  48. BPTR    EQU    <byte ptr>
  49. WPTR    EQU    <word ptr>
  50. DPTR    EQU    <dword ptr>
  51.  
  52. CIR0    EQU    0   ; command interface register 0
  53. CIR1    EQU    1   ; command interface register 1
  54. CIR2    EQU    2   ; command interface register 2
  55. CIR3    EQU    3   ; command interface register 3
  56. AR    EQU    4   ; attention register
  57. BCR    EQU    5   ; basic control reg
  58. ISR    EQU    6   ; interrupt status register
  59. BSR    EQU    7   ; basic status register
  60.  
  61. LONGSCB EQU   40h   ; long SCB attention request code
  62. NORMSCB EQU   30h   ; normal SCB attention request code
  63. IMMDCMD EQU   10h   ; immediate command
  64.  
  65.  
  66.  
  67. WAIT400 EQU    27   ; 27 15.625 intervals for 400 us wait (a little longer)
  68. WAIT50    EQU    4   ; 4 intervals for 50 us wait
  69.  
  70.  
  71.  
  72. BUSY    EQU   01h   ; busy bit
  73.  
  74.  
  75.  
  76.  
  77.     public    __StartIO
  78.     public    _ReadReg
  79.     public    _WriteReg
  80.     public    _WriteAttn
  81.     public    _ResetToggle
  82.  
  83.  
  84. _TEXT    segment word public 'code'
  85.     assume    cs:_TEXT
  86.  
  87. .286p
  88.  
  89.  
  90. ;/*************************************************************************/
  91. ;/*                                      */
  92. ;/* StartIO - Start an SCB to the specified device.              */
  93. ;/*                                      */
  94. ;/*    This routine will start the SCB on the device passed.          */
  95. ;/*                                      */
  96. ;/*      Entry: StartSCB(USHORT IOAddr,ULONG ppSCB, USHORT cmd);      */
  97. ;/*                                      */
  98. ;/*            IOAddr - I/O base address of the card          */
  99. ;/*            ppSCB  - phys ptr to SCB or the immediate command      */
  100. ;/*            cmd    - command to write to the attention register.  */
  101. ;/*                 It includes the logical device number and      */
  102. ;/*                 the request code.    Only the low byte is used */
  103. ;/*                                      */
  104. ;/*      Exit:  AX = 0 if no error, <> 0 if busy never cleared.      */
  105. ;/*         ints disabled if started (AX = 0)              */
  106. ;/*                                      */
  107. ;/*************************************************************************/
  108.  
  109. ;
  110. ; Stack frame, accounts for bp pushed on stack by enter instruction
  111.  
  112.  
  113. IOAddr        EQU     <(WPTR [bp+4])>     ; IO base address
  114. ppSCB        EQU     <(DPTR [bp+6])>     ; physical ptr to the SCB
  115. cmd        EQU     <(WPTR [bp+10])>     ; command to the adapter.
  116.  
  117.  
  118. __StartIO    proc    near
  119.  
  120.     enter    0,0
  121.  
  122. ;
  123. ;    First wait for busy to be cleared
  124.  
  125.     push    dx
  126.     push    cx
  127.  
  128.     mov    cx, WAIT400    ; 400 us wait
  129.     mov    dx, IOAddr    ; card IO address
  130.     call    wbsy        ; go wait
  131.  
  132.     jc    bsy        ; card is busy, something wrong
  133.  
  134. ;
  135. ;    Card is not busy and ints are off now.    Program the Command interface
  136. ;    registers with the SCB address.
  137.  
  138. .386p
  139.     mov    eax, ppSCB    ; get the physical address
  140.     mov    cx, 4        ; loop 4 times
  141. outl:    out    dx, al        ; out the low byte
  142.     inc    dx        ; next CIR
  143.     shr    eax, 8        ; shift next byte into al
  144.     loop    outl        ; go loop
  145.  
  146. .286p
  147.  
  148. ;
  149. ;    Now get the command code from the stack and write the low byte to
  150. ;    the attention register.
  151.  
  152.     mov    ax, cmd     ; get logical device number from stack
  153.     mov    dx, IOAddr    ; get base I/O address
  154.     add    dx, AR        ; attention register offset
  155.     out    dx, al        ; start the I/0
  156.     mov    ax, 0        ; no error
  157.     jmp    exit        ; leave
  158.  
  159. bsy:    mov    ax, 1        ; signal some error
  160.  
  161. exit:    pop    cx        ; restore stack
  162.     pop    dx
  163.  
  164.     leave
  165.     ret
  166.  
  167. __StartIO    endp
  168.  
  169.  
  170. ;/*************************************************************************/
  171. ;/*                                      */
  172. ;/* ReadReg - read the specified adapter register.              */
  173. ;/*                                      */
  174. ;/*    This routine reads the register pointed to by IOAddr and returns   */
  175. ;/*    the value in AX.                           */
  176. ;/*                                      */
  177. ;/*      Entry: ReadReg(USHORT IOAddr);                  */
  178. ;/*                                      */
  179. ;/*      Exit:  AL = register value                      */
  180. ;/*                                      */
  181. ;/*************************************************************************/
  182.  
  183. ;
  184. ; Stack frame, accounts for bp pushed on stack by enter instruction
  185.  
  186.  
  187. IOAddr        EQU     <(WPTR [bp+4])>     ; IO reg address
  188.  
  189. _ReadReg  proc    near
  190.  
  191.     enter    0,0
  192.  
  193.     push    dx           ; save DX
  194.     mov    dx, IOAddr     ; get register address
  195.     in    al, dx           ; read it
  196.     pop    dx           ; restore dx
  197.     leave               ; clear stack frame
  198.     ret               ; return to caller
  199.  
  200. _ReadReg  endp
  201.  
  202.  
  203. ;/*************************************************************************/
  204. ;/*                                      */
  205. ;/* WriteReg - write adapter register.                      */
  206. ;/*                                      */
  207. ;/*    This routine writes the low byte of the value on the stack to the  */
  208. ;/*    specified register.  This should not be used for writing to the      */
  209. ;/*    attention register.                          */
  210. ;/*                                      */
  211. ;/*      Entry: WriteReg(USHORT IOAddr, USHORT val);              */
  212. ;/*                                      */
  213. ;/*      Exit:  None.                              */
  214. ;/*                                      */
  215. ;/*************************************************************************/
  216.  
  217. ;
  218. ; Stack frame, accounts for bp pushed on stack by enter instruction
  219.  
  220.  
  221. IOAddr        EQU     <(WPTR [bp+4])>     ; IO reg address
  222. val        EQU     <(WPTR [bp+6])>     ; value
  223.  
  224. _WriteReg  proc  near
  225.  
  226.     enter    0,0
  227.  
  228.     push    dx           ; save DX
  229.     push    ax           ; save AX
  230.     mov    ax, val        ; get value to write out (low byte only)
  231.     mov    dx, IOAddr     ; get register address
  232.     out    dx, al           ; write the low byte out
  233.     pop    ax           ; restore ax
  234.     pop    dx           ; restore dx
  235.     leave               ; clear stack frame
  236.     ret               ; return to caller
  237.  
  238. _WriteReg  endp
  239.  
  240.  
  241. ;/*************************************************************************/
  242. ;/*                                      */
  243. ;/* WriteAttn - write the attention register.                  */
  244. ;/*                                      */
  245. ;/*    This routine writes the low byte of the value on the stack to the  */
  246. ;/*    attention register of the specified adapter.  It checks to make      */
  247. ;/*    sure that busy is clear before doing the write.              */
  248. ;/*                                      */
  249. ;/*      Entry: WriteReg(USHORT IOAddr, USHORT val);              */
  250. ;/*                                      */
  251. ;/*      Exit:  0 = no error, <>0 = error                  */
  252. ;/*                                      */
  253. ;/*************************************************************************/
  254.  
  255. ;
  256. ; Stack frame, accounts for bp pushed on stack by enter instruction
  257.  
  258.  
  259. IOAddr        EQU     <(WPTR [bp+4])>     ; base IO address
  260. val        EQU     <(WPTR [bp+6])>     ; value
  261.  
  262. _WriteAttn  proc  near
  263.  
  264.     enter    0,0
  265.  
  266. ;
  267. ;    First wait for busy to be cleared
  268.  
  269.     push    dx
  270.     push    cx
  271.  
  272.     mov    cx, WAIT400    ; 400 us wait
  273.     mov    dx, IOAddr    ; card IO address
  274.     call    wbsy        ; go wait
  275.  
  276.     jc    hosed        ; card is busy, something wrong
  277.  
  278.     mov    ax, val     ; get value to write out (low byte only)
  279.     mov    dx, IOAddr    ; get the base IO address
  280.     add    dx, AR        ; get to the attention register
  281.     out    dx, al        ; write the low byte out
  282.     mov    ax, 0        ; no error
  283.     jmp    allok
  284.  
  285. hosed:    mov    ax, 1        ; error
  286.  
  287. allok:    pop    cx        ; restore ax
  288.     pop    dx        ; restore dx
  289.     sti
  290.     leave            ; clear stack frame
  291.     ret            ; return to caller
  292.  
  293. _WriteAttn  endp
  294.  
  295. ;------ wbsy ---------------------------------------------------------------
  296. ; fixed time wait routine (memory refresh output used as reference)
  297. ;  as well as the busy indicator in the BSR
  298. ;
  299. ; entry:
  300. ;    cx    - count of 15.625 microsecond intervals to wait
  301. ;    dx    - base port value
  302. ;
  303. ; exit:
  304. ;    CFL    - 1, card busy, IFL unchanged
  305. ;          0, card is idle and IFL disabled
  306. ;    cx    - undefined
  307. ;---------------------------------------------------------------------------
  308. wbsy    proc    near            ; 
  309.     push    ax            ; save reg
  310.     push    dx            ; save port base
  311.     add    dx,BSR
  312. wbsy1:                    ; 
  313.     pushf                ; save current IFL
  314.     cli                ; disable ints
  315.     in    al,dx            ; eyeball BSR for not busy condition
  316.     test    al,BUSY         ; is card still busy?
  317.     jz    not_bsy         ; nope - exit loop w/ IFL=0, CFL=0
  318.     popf                ; restore IFL
  319.     in    al,61h            ; read current refresh request output
  320.     and    al,10h            ; mask for refresh request bit
  321.     cmp    al,ah            ; did it just change
  322.     je    wbsy1            ; wait for a change
  323.     mov    ah,al            ; save new state
  324.     loop    wbsy1            ; decrement half cycles till count end
  325.     stc                ; time expired - CFL set means error
  326.     jmp    short wb1        ; exit
  327.  
  328. not_bsy:                ; (CFL=0)
  329.     pop    ax            ; balance stack (throw away flags)
  330. wb1:
  331.     pop    dx            ; restore base port
  332.     pop    ax            ; restore ax
  333.     ret                ;  exit - CFL is clear
  334.  
  335. wbsy    endp
  336.  
  337.  
  338. ;/*************************************************************************/
  339. ;/*                                      */
  340. ;/* _ResetToggle                              */
  341. ;/*                                      */
  342. ;/*    This routine will reset the specified adapter by toggling the      */
  343. ;/*    sub-system reset bit in the basic control register.          */
  344. ;/*                                      */
  345. ;/*      Entry: _ResetToggle (USHORT baseIO)                  */
  346. ;/*                                      */
  347. ;/*      Exit:  0 always                          */
  348. ;/*                                      */
  349. ;/*************************************************************************/
  350.  
  351. ;
  352. ; Stack frame, accounts for bp pushed on stack by enter instruction
  353.  
  354.  
  355. baseIO        EQU     <(WPTR [bp+4])>     ; base IO address
  356.  
  357. _ResetToggle  proc  near
  358.  
  359.     enter    0,0
  360.  
  361. ;
  362. ;    Get current BCR value, mask some bits off and save it
  363.  
  364.     mov    dx, baseIO        ; base IO
  365.     add    dx, BCR         ; pt to basic control reg
  366.     in    al, dx            ; get current value
  367.     and    al, 0fh         ; mask off high nibble
  368.     push    ax            ; save value
  369.  
  370. ;
  371. ;    Now write the reset bit on, wait 50 us and then turn it off.
  372. ;    Use memory refresh as a counter.
  373.  
  374.     mov    al, 80h
  375.     out    dx, al            ; reset bit on
  376.     mov    cx, 4            ; wait at least 50 us
  377.  
  378. @@:                    ; 
  379.     in    al,61h            ; read current refresh request output
  380.     and    al,10h            ; mask for refresh request bit
  381.     cmp    al,ah            ; did it just change
  382.     je    @b            ; wait for a change
  383.     mov    ah,al            ; save new state
  384.     loop    @b            ; decrement half cycles till count end
  385.  
  386.     mov    al, 00h
  387.     out    dx, al            ; now turn it off
  388.  
  389. ;
  390. ;    Now program it back to the original value, minus a few bits.
  391.  
  392.     pop    ax            ; original value
  393.     out    dx, al            ; write it back
  394.  
  395.     leave
  396.     ret
  397.  
  398. _ResetToggle  endp
  399.  
  400.  
  401. _TEXT    ends
  402.     end
  403.