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