dskcntl.asm
name dskcntrl
page 55,80
title 'DSKCNTRL.ASM -- Turn hard disk on/off'
;
; Synpet Personal Technologies, Inc.
; 7225 Franklin Rd, Boise, ID 83709
;
; Created 1/28/90 - LRE
;
;
;
; Turn hard disk off after n seconds of inactivity. Turn back on if
; disk bios call occurs.
; The following disk control functions are available by doing a FAR
; call to the dsk_prog_cntrl procedure.
; Call with the number of the function desired in the ah register.
; Returns 0 in register al if successful. Returns 0ffh in al if
; called with an invalid function number. Returns 0feh in al if
; called with other than the install function when dskcntrl has not
; been installed yet, or is currently uninstalled.
;
; Function 0 - Turn off disk control. Turns on the disk if currently
; off. Disables the time out function, leaving the disk
; on.
; Function 1 - Turn on disk control. Enables the disk time out function
; if previously turned off. A NOP function if called
; while diskcontrol is on.
; Function 2 - Turn off disk. - Unconditionally turns off disk, even
; if time out has not occurred, or disk control is off.
; Any disk access after this command is executed will
; still turn on the disk.
; Function 3 - Turn on disk. - Unconditionally turns on disk. If disk
; control is on, restarts time out.
; Function 4 - Change disk time out. Enter with the bx register holding
; the new time out value as int(seconds * 18.2).
; Function 5 - Install disk control. Starts the disk control functions
; running by chaining to the BIOS timer tic and to the
; BIOS disk control interrupt.
; Function 6 - Uninstall disk control. Restores the BIOS interrupts to
; their previous vectors. MUST be called before any
; program using disk control exits, or the computer will
; crash.
disk_port_add equ 0302h ;
disk_stop_byte equ 01h ;
disk_start_byte equ 00h ;
disk_def_time_out equ 1092 ; Seconds times 18.2.
disk_spin_up_time equ 1092 ;
cseg segment para public 'CODE'
assume cs:cseg,ds:cseg,es:cseg,ss:cseg
public dsk_prog_cntrl
; Disk control variables.
time_tic_chain_add dd 0 ;
disk_int_chain_add dd 0 ;
dsk_cntrl_seg dw 0 ;
disk_time_out dw disk_def_time_out ;
disk_tic dw 0 ;
disk_spin_up_tic dw 0 ;
disk_stopped db 0 ;
control_off db 0 ;
installed_flag db 0 ;
timer_tic proc far
pushf ;
push ax ;
mov al,cs:control_off ;
or al,al ;
jnz no_disk_tic_inc ;
cmp cs:disk_spin_up_tic,disk_spin_up_time ;
je no_spin_up_tic_inc ;
inc cs:disk_spin_up_tic ;
no_spin_up_tic_inc:
mov ax,cs:disk_time_out ;
cmp cs:disk_tic,ax ;
je no_disk_tic_inc ;
inc cs:disk_tic ;
cmp cs:disk_tic,ax ;
jne no_disk_tic_inc ;
push dx ;
mov dx,disk_port_add ;
mov al,disk_stop_byte ;
out dx,al ;
mov cs:disk_stopped,0ffh ;
pop dx ;
no_disk_tic_inc:
pop ax ;
popf ;
jmp cs:time_tic_chain_add ;
timer_tic endp
disk_int_tic proc far
pushf ;
push ax ;
mov cs:disk_tic,0 ;
cmp cs:disk_stopped,0 ;
jz disk_is_on ;
disk_is_stopped:
call startup_disk ;
disk_is_on:
pop ax ;
popf ;
jmp cs:disk_int_chain_add ;
disk_int_tic endp
startup_disk proc near
push ax ;
push bx ;
push cx ;
push dx ;
push si ;
push di ;
push bp ;
push ds ;
push es ;
mov dx,disk_port_add ;
mov al,disk_start_byte ;
out dx,al ;
mov cs:disk_stopped,0 ;
mov cs:disk_spin_up_tic,0 ;
sti ;
try_spinup:
mov ah,0 ;
int 63h ;
mov ah,1 ;
int 63h ;
and al,al ;
jz done_with_spinup ;
cmp cs:disk_spin_up_tic,disk_spin_up_time ;
jnc done_with_spinup ;
jmp try_spinup ;
done_with_spinup:
mov cs:disk_spin_up_tic,disk_spin_up_time ;
pop es ;
pop ds ;
pop bp ;
pop di ;
pop si ;
pop dx ;
pop cx ;
pop bx ;
pop ax ;
ret ;
startup_disk endp
dsk_prog_cntrl proc far
cmp ah,5 ;
jz do_init_dsk_cntrl ;
push ax ;
mov al,cs:installed_flag ;
or al,al ;
pop ax ;
jz uninstalled_error ;
cmp ah,0 ;
jz turn_off_dsk_cntrl ;
cmp ah,1 ;
jz turn_on_dsk_cntrl ;
cmp ah,2 ;
jz turn_off_dsk ;
cmp ah,3 ;
jz turn_on_dsk ;
cmp ah,4 ;
jz change_dsk_time_out ;
cmp ah,6 ;
jz do_uninstall_dsk_cntrl ;
mov al,0ffh ;
ret ;
uninstalled_error:
mov al,0feh ;
ret ;
turn_off_dsk_cntrl:
mov cs:control_off,0ffh ;
turn_on_dsk:
mov cs:disk_tic,0 ;
cmp cs:disk_stopped,0 ;
jz dsk_already_on ;
call startup_disk ;
dsk_already_on:
xor al,al ;
ret ;
turn_on_dsk_cntrl:
mov cs:control_off,0 ;
xor al,al ;
ret ;
turn_off_dsk:
push dx ;
mov dx,disk_port_add ;
mov al,disk_stop_byte ;
out dx,al ;
mov cs:disk_stopped,0ffh ;
pop dx ;
xor al,al ;
ret ;
change_dsk_time_out:
mov cs:disk_tic,0 ;
mov cs:disk_time_out,bx ;
xor al,al ;
ret ;
do_init_dsk_cntrl:
call init_dsk_cntrl ;
ret ;
do_uninstall_dsk_cntrl:
call uninstall_dsk_cntrl ;
ret ;
dsk_prog_cntrl endp
init_dsk_cntrl proc near
; Set timer tic address & chain address to old.
mov al,cs:installed_flag ;
or al,al ;
jz install ;
xor al,al ;
ret ;
install:
push ds ;
mov cs:disk_tic,0 ;
mov ax,351ch ;
int 21h ;
mov cs:word ptr time_tic_chain_add,bx ;
mov cs:word ptr time_tic_chain_add + 2,es ;
push cs ;
pop ds ;
mov dx,offset timer_tic ;
mov ax,251ch ;
int 21h ;
; Set bios disk int address & chain address to old.
mov ax,3513h ;
int 21h ;
mov cs:word ptr disk_int_chain_add,bx ;
mov cs:word ptr disk_int_chain_add + 2,es ;
; Set bios disk int address we can use.
push es ;
pop ds ;
push bx ;
pop dx ;
mov ax,2563h ;
int 21h ;
push cs ;
pop ds ;
mov dx,offset disk_int_tic ;
mov ax,2513h ;
int 21h ;
pop ds ;
mov cs:installed_flag,0ffh ;
xor al,al ;
ret ;
init_dsk_cntrl endp
uninstall_dsk_cntrl proc near
; Restore timer int.
push ds ;
mov cs:disk_tic,0 ;
cmp cs:disk_stopped,0 ;
jz uninstall_dsk_already_on ;
call startup_disk ;
uninstall_dsk_already_on:
mov dx,cs:word ptr time_tic_chain_add + 2 ;
mov ds,dx ;
mov dx,cs:word ptr time_tic_chain_add ;
mov ax,251ch ;
int 21h ;
mov dx,cs:word ptr disk_int_chain_add + 2 ;
mov ds,dx ;
mov dx,cs:word ptr disk_int_chain_add ;
mov ax,2513h ;
int 21h ;
pop ds ;
mov cs:installed_flag,0 ;
xor al,al ;
ret ;
uninstall_dsk_cntrl endp
cseg ends
end