TIP: Click on subject to list as thread! ANSI
echo: power_bas
to: SANDER SMEENK
from: SCOTT MCNAY
date: 1996-05-01 23:45:00
subject: Spin Down

Hello Sander!
SS> Does anyone have the source (may be ASM / C / Pascal) to spin down
SS> drives. Not only the primary drive installed, but every drive you
SS> want. (Coz I have 2 drivez, and a prog that only spinns down one of
SS> them...) 
How about a piece of code and snippets from my notes?  If you can't get it to 
work, netmail me and I'll send you some working code.
CurrentPort has the value 1F0 (primary port), 170 (secondary), 1E8 
(tertiary), 168 (quarternary), as appropriate.
*************************************************
HDData          equ     0       ; Low byte of data register
HDError         equ     1       ; Error flags, high byte of data register
 7 = Bad block detected
 6 = uncorrectable ECC error
 5 = "reserved"
 4 = ID found (this is an error??)
 3 = "reserved"
 2 = command completed
 1 = track 0 not found
 0 = DAM not found (always found (=0) on CP-3022)
HDPrecomp       equ     1       ; Precomp (WPC/4)
HDNSector       equ     2       ; # Sectors to read/write
HDSector        equ     3       ; Starting sector
HDLCyl          equ     4       ; Starting cylinder, low byte
HDHcyl          equ     5       ; Starting cylinder, high byte
HDCurrent       equ     6       ; 1L1DHHHH, L=LBA (0=CHS), D=drive, H=head
HDStatus        equ     7       ; Status
 ErrStatus       equ     1h      ; Previous comand ended in error
 IndexStatus     equ     2h      ; Setto 1 each disk rev
 EccStatus       equ     4h      ; Corrected error
 DrqStatus       equ     8h      ; Ready for data xfer
 SeekStatus      equ     10h     ; Seek complete
 WrerrStatus     equ     20h     ; write fault
 ReadyStatus     equ     40h     ; Drive is ready
 BusyStatus      equ     80h     ; Drive executing a command
HDCommand       equ     7       ; Command register
                 98h     check power mode       (IDE)
                 97h     idle                   (IDE)
                 95h     idle immediate         (IDE)
                 99h     set sleep mode         (IDE)
                 96h     standby                (IDE)
                 94h     standby immediate      (IDE)
3F6 = 00000010 Software reset.  Ends sleep mode.
 (= CurrentPort+206h)
;               Wait for idle
   mov     bl,BusyStatus
   call    WaitStatus
   jc      NoIDEData
   mov     dx,CurrentPort
   add     dx,HDCurrent
   mov     al,CurrentDrive
   out     dx,al           ; Drive, Head, CHS mode
   jmp     $+2
   inc     dx
   mov     al,SleepCmd
   out     dx,al           ; Command
;
; Drive presumably goes to sleep at this point, not tested.  ;)
;
; ...
; Wake drive up.  Again, not tested
        mov      dx,CurrentPort
        add      dx,206h
        mov      al,000000010b
        out      dx,al
; Next call WaitStatus to wait for drive to become ready again.
***********************************
; Here's the WaitStatus subroutine.  I threw it in here tosave you from 
wasting ; your time coding the same thing.  Please note that accessing the 
tertiary and ; quarternary ports will lock the system.  This is not a problem 
with this ; routine.  ;)
WaitStatus:
; Input: BL = Bit pattern to look for
; Output: Z = Condition found
;         NZ = Timeout or keyboard abort
; Uses: CurrentPort, HDStatus, [0:6C], TimeoutMsg, KeyAbortMsg
; Changes: ax, cx, dx, di, si
; Description: Waits for specific ST402/IDE/ESDI status condition to occur.
; Aborts after 45 seconds (should take max of 31 secs), or after keystroke.
;
   mov     dx,CurrentPort
   add     dx,HDStatus
   push    ds
   xor     ax,ax
   mov     ds,ax
   assume  ds:BIOS
   mov     si,ax
   mov     cx,TimerLow
   mov     si,cx
   sub     cx,si
   add     cx,819                  ;18.2 * 45: Wait 45 seconds
   jmp     @f
@@:
   in      al,dx                   ; Check for desired condition
   test    bl,010000000b           ; Are we checking for busy?
   jnz     Reverse
   test    al,bl
   jnz     @f
   test    al,001000000b           ;Are we checking for ready?
   jnz     EndReverse
   mov     dx,offset ErrMsg
   jmp     PrintErrorMsg1
Reverse:
   test    al,bl
   jz      @f
EndReverse:
   pusha                           ; Check for keyboard abort
   mov     ah,1
   int     16h
   popa
   jnz     KeyAbort
   mov     ax,TimerLow             ; Check for timeout
   sub     ax,si
   cmp     ax,cx
   jb      @b
TimeOut:
   mov     dx,offset TimeoutMsg
PrintErrorMsg1:
   pop     ds
PrintErrorMsg:
   mov     ah,9
   int     21h
   stc
   ret
@@:
   clc
   pop     ds
   assume  ds:IDE
EndWaitStatus:
   ret
KeyAbort:
   xor     ah,ah
   int     16h
   cmp     al,1Bh
   je      QuitNow2
   mov     dx,offset KeyAbortMsg
   jmp     PrintErrorMsg1
**********************************
Here's the details from the specs.
                          Table 7 - Power conditions
+===================================================+
|   Mode   |SRST| BSY |DRDY| Interface active |Media|
|----------+----+-----+----+------------------+-----|
| Sleep    |  * |  x  |  x |         *        |  0  |
| Standby  |  x |  0  |  1 |        Yes       |  0  |
| Idle     |  x |  0  |  1 |        Yes       |  1  |
| Active   |  x |  x  |  x |        Yes       |  1  |
|---------------------------------------------------|
|   1 = Active    0 = Inactive         * See 9.23   |
+===================================================+
The lowest power consumption when the drive is powered on occurs in Sleep
mode.  When in Sleep mode, the drive requires a reset to be activated (see
9.23).  The time to respond could be as long as 30 seconds or more.
In Standby mode the drive interface is capable of accepting commands, but as
the media is not immediately accessible, it could take the drive as long as
30 seconds or more to respond.
In Idle mode the drive is capable of responding immediately to media access
requests.  A drive in Idle mode may take longer to complete the execution of
a command because it may have to activate some circuitry.
In Active mode the drive is capable of responding immediately to media access
requests, and commands complete execution in the shortest possible time.
                         Table 8 - Register contents
+======================================================================+
|                        |       Error register       | Status register|
|------------------------+----------------------------+----------------|
|                        |BBK|UNC|IDNF|ABRT|TK0NF|AMNF|DRDY|DWF|DSC|ERR|
|------------------------+---+---+----+----+-----+----+----+---+---+---|
| Check power mode       |   |   |    |  V |     |    |  V | V | V | V |
| Idle                   |   |   |    |  V |     |    |  V | V | V | V |
| Idle immediate         |   |   |    |  V |     |    |  V | V | V | V |
| Sleep                  |   |   |    |  V |     |    |  V | V | V | V |
| Standby                |   |   |    |  V |     |    |  V | V | V | V |
| Standby immediate      |   |   |    |  V |     |    |  V | V | V | V |
|------------------------+---+---+----+----+-----+----+----+---+---+---|
| V = valid on this command                                            |
+======================================================================+
                          Table 9 - Command codes and parameters
+==================================================================+
|                                      |       |  Parameters used  |
|                                      |Command|-------------------|
|                                      | code  | SC | SN | CY | DH |
|--------------------------------------+-------+----+----+----+----|
| Check power mode                     |98h    |  y |    |    |  D |
| Idle                                 |97h    |  y |    |    |  D |
| Idle immediate                       |95h    |    |    |    |  D |
| Sleep                                |99h    |    |    |    |  D |
| Standby                              |96h    |  y |    |    |  D |
| Standby immediate                    |94h    |    |    |    |  D |
|------------------------------------------------------------------|
| DH = Drive/head register        SC = Sector count register       |
| y - the register contains a valid parameter for this command.    |
|     For the drive/head register, y means both the drive and      |
|     head parameters are used.                                    |
| D - only the drive parameter is valid and not the head parameter.|
+==================================================================+
9.4 Check power mode
This command checks the power mode.
If the drive is in, going to, or recovering from the Standby Mode the drive
shall set BSY, set the Sector Count Register to 00h, clear BSY, and generate
an interrupt.
If the drive is in the Idle Mode, the drive shall set BSY, set the Sector
Count Register to FFh, clear BSY, and generate an interrupt.
9.10 Idle
This command causes the drive to set BSY, enter the Idle Mode, clear BSY, and
generate an interrupt.  The interrupt is generated even though the drive may
not have fully transitioned to Idle Mode.
If the drive is already spinning, the spinup sequence is not executed.
If the Sector Count Register is non-zero then the automatic power down
sequence shall be enabled and the timer begins counting down immediately.  If
the Sector Count Register is zero then the automatic power down sequence 
hall
be disabled.
9.11 Idle immediate
This command causes the drive to set BSY, enter the Idle Mode, clear BSY, and
generate an interrupt.  The interrupt is generated even though the drive may
not have fully transitioned to Idle Mode.
9.24 Sleep
This command is the only way to cause the drive to enter Sleep Mode.  The
drive is spun down, and when it is stopped, BSY is cleared, an interrupt is
generated, and the interface becomes inactive.
The only way to recover from Sleep mode is with a software reset or a 
ardware
reset.
    NOTE 12 - The use of hardware reset to recover from Sleep mode may be
    incompatible with continued operation of the host system.
A drive shall not power on in Sleep Mode nor remain in Sleep Mode following
a reset sequence.  If the drive is already spun down, the spin down sequence
is not executed.
9.25 Standby
This command causes the drive to enter the Standby Mode.  See 10.3 for
protocol.  The drive may return the interrupt before the transition to 
tandby
Mode is completed.
If the drive is already spun down, the spin down sequence is not executed.
If the Sector Count Register is non-zero then the automatic power down
sequence shall be enabled and the timer will begin counting down when the
drive returns to Idle mode.  If the Sector Count Register is zero then the
automatic power down sequence shall be disabled.
9.26 Standby immediate
This command causes the drive to enter the Standby Mode.  See 10.3 for
protocol.  The drive may return the interrupt before the transition to 
tandby
Mode is completed.
If the drive is already spun down, the spin down sequence is not executed.
10.3  Non-data commands
This class includes:
    -   Idle;
    -   Read power mode;
    -   Standby.
Execution of these commands involves no data transfer.
    a)  The host writes any required parameters to the Features, Sector 
ount,
        Sector Number, Cylinder, and Drive/Head registers.
    b)  The host writes the command code to the Command Register.
    c)  The drive sets BSY.
    d)  When the drive has completed processing, it clears BSY and asserts
        INTRQ.
    g)  The host reads the Status Register.
    h)  The drive negates INTRQ.
--Scott.
--- timEd/386 1.10
---------------
* Origin: Wizard, 817-526-6546, sponsored by Abacus: 634-8006 (1:395/11)

SOURCE: echomail via exec-pc

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.