home *** CD-ROM | disk | FTP | other *** search
- PAGE 60,120
- TITLE TSRPARK.ASM -- TesSeRact Demo program to park disk drive heads
- ;----------------------------------------------------------------------------
- SUBTTL Originally TESSPARK.ASM : TesSeRact Revision Level 1
- ;-----------------------------------------------------------------------------
- ; TesSeRact(tm) -- A Library of Routines for Creating Ram-Resident (TSR)
- ; programs for the IBM PC and compatible Personal
- ; Computers.
- ;
- ;The software, documentation and source code are:
- ;
- ; Copyright (C) 1986, 1987, 1988 Tesseract Development Team
- ; All Rights Reserved
- ;
- ; c/o Chip Rabinowitz
- ; Innovative Data Concepts
- ; 2084 Woodlawn Avenue
- ; Glenside, PA 19038
- ; 1-215-884-3373
- ;
- ;-----------------------------------------------------------------------------
- ; This product supports the TesSeRact Standard for Ram-Resident Program
- ; Communication. For information about TesSeRact, contact the TesSeRact
- ; Development Team at:
- ; Compuserve: 70731,20
- ; MCIMAIL: 315-5415
- ; This MCIMAIL Account has been provided to the TesSeRact Development
- ; Team by Borland International, Inc. The TesSeRact Development Team
- ; is in no way associated with Borland International, Inc.
- ;-----------------------------------------------------------------------------
- ;
- ; BASED on code originally provided by Jim Mischel
- ;
- ; ORIGINAL COPYRIGHT NOTICE:
- ;
- ;;;; AUTOPARK.ASM - program to automatically park the disk drive heads
- ;;;; at specified time intervals.
- ;;;;
- ;;;; Copyright (c) 1988, Jim Mischel
- ;;;;
- ;;;; This program has been assembled using MASM 5.0. Changes may be required
- ;;;; for use with earlier versions.
- ;;;;
-
- ;;;;; TSRPARK.ASM - Rick Housh
- ;;;;;
- ;;;;; TSRPARK.ASM - Modifications to TESSPARK.ASM to allow variable timing
- ;;;;; intervals from 1 to 9 minutes for autopark with use of numerical
- ;;;;; parameter on command line, to support manual parking with use
- ;;;;; of hotkey, with popup when on DOS command line, detection of
- ;;;;; park failure on installation, and communication with the resident
- ;;;;; program to allow dynamically changing the elapsed time between
- ;;;;; automatic parks. Assembled using MASM 5.1.
- ;;;;;
- ;;;;; Everything is self-explanatory, except perhaps how to reset the
- ;;;;; timer when resident. Just enter ' TSRPARK # ', where # is any number
- ;;;;; of minutes between 1 and 9, and the new value will be inserted in the
- ;;;;; resident portion of the program. A message will confirm the change
- ;;;;; and even the MAPMEM display of residents will show the new value.
- ;;;;; Entering ' TSRPARK ' with no parameter will yield a confirming message
- ;;;;; if TSRPARK is resident, and an instructional message if it has not
- ;;;;; yet been installed. When the hotkey is pressed from the DOS prompt
- ;;;;; a message is displayed, in addition to the TESSBEEP sound. Inside
- ;;;;; a program, the sound will occur, but there will be no message.
- ;;;;;
- ;;;;; I have changed the "mysterious" headparking code somewhat, and tried
- ;;;;; to expand the comments to show how it really works. It's not that
- ;;;;; complicated, and does NOT care whether the computer is an AT or not,
- ;;;;; contrary to the comments in the original TESSPARK. I have also found
- ;;;;; an undocumented and useful function. Tch, tch. TSRCHECKRESIDENT
- ;;;;; returns the segment of the resident program in the es register if
- ;;;;; it has found the program installed in memory. The documentation
- ;;;;; only mentions a result returned in the ax register. I found this
- ;;;;; very useful, and have implemented in TSRPARK.
- ;;;;;
- ;;;;; TSRPARK Modifications of TESSPARK, Rick Housh, CIS 72466,212 - 7/18/1988
- ;;;;;
-
- ;;;;;
- ;;;;; To assemble this TesSeRact version:
- ;;;;;
- ;;;;; MASM TSRPARK;
- ;;;;; LINK TESS_ASM + TESS_BP + TSRPARK + TESS_END,TSRPARK;
- ;;;;; EXE2BIN TSRPARK.EXE TSRPARK.COM
- ;;;;;
-
- .model small
-
- .code
-
- ;
- ; Ticks2wait is # of timer ticks to wait between the last disk access
- ; and parking the disk. There are approximately 18.2 ticks per second.
- ;
- ; Maximum possible ticks2wait is 65536 ticks, very close to 1 hour.
- ; Limit with this configuration is 9828 (9 minutes).
- ;
-
- ticks_min equ 1092 ;Number of timer ticks in 1 minute
- tinkle equ 1 ;Sound TESSBEEP if set
- ;set tinkle to 0
- ;for no sound
- tick_count dw ? ;Current count
- ticks2wait dw ? ;Ticks to wait: 1092 = 1 minute
-
- ;
- ; The parkit routine attempts to park all hard disks.
- ; Returns with carry set if park was unsuccessful.
- ;
- parkit proc near
- mov si,0080h ;Hard drive id nos. start at 80h
- pk0: mov ah,08h ;Function gets drive parms.
- mov dx,si ;DX is drive ID No.
- int 13h ;Get drive parms, dl = No. of drives
- jc pkdone ;Error if carry, jump out
- xor dh,dh ;Don't need max head-side number
- mov di,dx ;Save drive count from dl to di
- cmp di,01h ;Is there at least one?
- jb pkdone ;If no hard drives, exit
- add di,7fh ;Convert drive no. to drive id no.
- inc ch ;CH is now tracks + 1
- jnb pk1
- add cl,40h ;CL is sectors
- pk1: mov ax,0c01h ;seek to cylinder
- mov dx,si ;DX is drive ID
- int 13h ;this does the seek
- inc si ;bump drive count
- cmp si,di ;Was it the last? No? Then
- jbe pk0 ;loop until all drives are parked
- pkdone:
- if tinkle
- EXTRN TESSBEEP:NEAR
-
- call TESSBEEP
- endif
- ret
- parkit endp
-
-
- ;
- ; TesSeRact Entry Points
- ;
- ;
- PUBLIC TSRUSERPROC, TSRTIMERPROC, TSRBACKCHECK, TSRMAIN, TSRBACKPROC
- PUBLIC TSRCLEANUP
-
- ;
- ; TSUSERPROC is a NULL procedure. We don't service it in this program.
- ;
- ;
- TSRUSERPROC: ;Return, does nothing
- ret
-
- int13ptr dw 0 ;Saved location of INT 13 flag
- ; from TesSeRact data area
- do_park db 0 ;Flag set to 1 when wish to park
-
- TSRminutes db " " ;Holds minutes between parks in ASCII
-
- park_msg label near ;Message to display when popped up
- ; AND at DOS prompt
- db 13,10,10
- db 'TSRPark has manually parked the hard disk(s)',13,10
- db 'as requested. Will automatically repark in ',13,10
- db ' minute(s) after next disk access. ',13
- msg_len dw $ - park_msg
-
- reset_it proc near
- mov do_park,0 ;Say not to park
- mov bx,[int13ptr] ;Get INT13 flag
- mov byte ptr [bx],0 ;and turn off because
- ;parking isn't using.
- mov ax,[ticks2wait] ;Use our timer to
- mov [tick_count],ax ;restart wait.
-
- ret
- reset_it endp
-
- TSRBACKCHECK proc near
- assume cs:_TEXT, ds:_TEXT
-
- mov al,do_park ;Put flag in ax
- xor ah,ah ;if non-zero, call TSRBACKPROC
- ret
- TSRBACKCHECK endp
-
- TSRBACKPROC proc near
- assume cs:_TEXT, ds:_TEXT
-
- call parkit ;Attempt to park it
- call reset_it ;and reset everything
-
- ret
- TSRBACKPROC endp
-
- TSRMAIN proc near
- assume cs:_TEXT, ds:_TEXT
- ;On hotkey
- call parkit ;Park disks
- call reset_it ;and reset flags and timer
- mov ax,5453h ;TesSerAct function
- mov bx,16h ;to get InDos state
- mov cx,ParkNum ;This ident #
- int 2fh ;Call function 16h
- cmp bx,1 ;Check if at DOS prompt
- jnz mainX ;and end if not
- mov ah,08h ;First read attribute
- mov bh,0 ;at current position
- int 10h ;then
- or ah,08h ;turn on intensity bit
- mov bl,ah ;and save it in bl
- mov si,offset park_msg ;Point to message
- mov cx,[msg_len] ;and its length
- putmsg: lodsb ;Load ASCII character
- cmp al,20h ;Is it lower than space?
- jb no_att ;then don't paint attribute
- push ax ;Save character
- mov ah,09h ;Paint an attribute
- mov al,20h ;with a space
- sub bh,bh ;on page zero
- push cx ;Save count
- mov cx,1 ;With this function
- int 10h ;cursor doesn't move
- pop cx ;Restore character count
- pop ax ;and ASCII character
- no_att: mov ah,0eh ;Set to print TTY
- sub bh,bh ;at page 0
- int 10h ;and print characters
- loop putmsg ;until end of string
- mov si,offset TSRminutes ;Display minutes
- lodsb ;Load a single character
- int 10h ;and display it
- mov al,10 ;Now a line feed
- int 10h ;with TTY display
- mov ax,5453h ;TesSeRact function to
- mov cx,ParkNum ;Stuff a CR into
- mov bx,21h ;Keyboard Buffer
- mov di,Offset park_msg ;Point to a 13
- mov si,1 ;(one character).
- mov dx,0101h ;ASCII - medium speed
- int 2fh ;call TesSerAct
- ;DOS prompt should be back.
- ;Can't correct error so no test.
- mainX: ret
- TSRMAIN endp
-
- TSRCLEANUP proc near
- assume cs:_TEXT, ds:_TEXT
-
- or ax,ax
- jnz clean_term
-
- clean_init:
- ;
- ; Please note that the data area returned by this function is also available
- ; as the TESS_GLOBALS public symbol.
- ;
- mov cx,ParkNum ;This program's ID num.
- mov bx,4h ;in data area
- mov ax,5453h ;Ready for multiplex
- int 2fh ;Call it, then point bx to
- add bx,3h ;offset of TesSerAct flag "Was13"
- mov int13ptr,bx ;and put in local pointer
- ;Since program owns segment
- ;no need to worry about it!
- clean_term: ;Nothing needed to terminate!
- clean_out:
- ret
- TSRCLEANUP endp
-
- TSRTIMERPROC proc near
- assume cs:_TEXT, ds:_TEXT
-
- mov bx,[int13ptr] ;Check to see if
- cmp byte ptr [bx],1 ;disk has been accessed
- jne no_park ;since last parked
- no_disk:
- mov [do_park],0 ;If no access, set park flag off
- dec [tick_count] ;decrement the timer
- jnz no_park ;and exit
- mov [do_park],1 ;else set park flag on
- clear_it:
- mov ax,[ticks2wait] ;Use our own parameter
- mov [tick_count],ax ;to restart wait
- mov byte ptr [bx],0 ;and clear flag
- no_park:
- ret
-
- TSRTIMERPROC endp
-
- ; If AUTOPARK already installed, display error message and exit.
- ; If not installed, attempt to park the disks and install the resident
- ; portion.
- ;
- EXTRN TSDOINIT:NEAR
- EXTRN TSCHECKRESIDENT:near
- EXTRN TSSETSTACK:near
-
- ParkNum dw 0 ;This ID number
- ParkName db 'TSRPARK ',0 ;This Identification string
-
- public topstack
- db 48 dup('Back_Gnd') ;BackProcStack - 384 bytes
- db 48 dup('TSR_Main') ;MainProcStack - 384 bytes
- topstack equ this byte
-
- PUBLIC TESSINITSTART ;required entry point
-
- TESSINITSTART:
- assume cs:_TEXT, ds:_TEXT
-
- jmp start_init
-
- get_cmd_line:
-
- mov si,80h ;Start of command line
- lodsb ;Command length
- cmp al,0 ;If nothing on command line
- jz cmd_err ;exit
- get_1: lodsb ;else get next character
- cmp al,13 ;A CR? Then end of line
- jz cmd_err ;with nothing legal. Exit.
- cmp al,"1" - 1 ;Is it < ASCII "1"?
- ja chk_9 ;No? Check for > "9"
- jmp short get_1 ;Yes? get another.
- chk_9: cmp al,"9" + 1 ;Above a nine?
- jb cmd_ok ;No? OK - between "1" and "9"
- jmp short get_1 ;Yes? Get another
- cmd_ok: mov [TSRminutes],al ;Is between 1 and 9, so
- ;save in TSR ASCII variable
- mov [minutes],al ;And in non-resident part too.
- and ax,0Fh ;Convert ASCII to numerical
- mov cx, ticks_min
- mul cx ;Multiply by ticks_min. (1092)
- mov di,offset tick_count
- stosw ;and initialize count
- stosw ;and wait timer value
- ;
- ;The next few bytes just stuff "# minute(s)." into the command line
- ;which will be carried along with the resident program, for MAPMEM
- ;or its ilk to see our wait time.
- ;
- mov si,offset signon ;Signon starts with a CR
- mov di,80h ;which is the value we need.
- movsb ;Move 13 to the length byte at 80h
- mov si,offset minutes ;Point source at '# minute(s).'
- mov di,82h ;destination at command line
- mov cx,13 ;and move 13 bytes
- stuff_loop: ;looping here
- movsb
- loop stuff_loop
-
- clc ;then, after clearing carry flag
- ret ;exit subroutine
- cmd_err:
- stc ;Set carry flag
- ret ;and return
-
- ;
- ; Although I can't find it in the version 1.00 TesSerAct documentation,
- ; TSRCHECKRESIDENT, if it finds the code resident, returns not only
- ; 0ffffh in ax but the segment of the resident version in the es register.
- ; This makes it unnecessasry to call multiplex function 4 to find
- ; its location. I will use that undocumented feature here, but
- ; we should have been told. - Rick Housh
- ;
-
- start_init:
- mov si,offset ParkName ;Check to see if
- mov di,offset ParkNum ;resident
- call TSCHECKRESIDENT ;Returns segment of resident
- ;program in es if installed
- or ax,ax ;If already installed
- jnz is_tsr ;then reset or display info msg
- jmp short do_install ;else install it
- is_tsr: call get_cmd_line ;If NOT valid command line
- jc just_checking ;just display status and exit
- mov al,[TSRMinutes] ;else get new value in ASCII
- mov es:[TSRMinutes],al ;and put it in resident code
- mov es:[82h],al ;and in resident cmd line for mapmem
- mov ax,[ticks2wait] ;Same with ticks to wait
- mov es:[ticks2wait],ax
- mov dx,offset tsr_reset ;Tell em have changed it
- mov ah,09h
- int 21h
- jmp short display_time ;and display new value
- just_checking:
- mov dx,offset already_installed ;Already installed
- mov ah,09h ;and no change, requested so
- int 21h ;display status message and exit
- display_time:
- mov al,es:[TSRMinutes] ;Get minutes from resident code
- mov [minutes],al ;move resident value here
- mov dx,offset auto_time ;and display
- int 21h ;current TSR minute value
-
- term_it:
- mov ax,4c01h ;Set error code to 1
- int 21h ;and quit
-
- do_install: ;"Take care of stack early"
- mov si,offset topstack ;Because using both,
- mov di,si ;divide stack area
- dec di ;into areas for
- dec di ;PopUpStack and
- sub si,384 ;BackGroundStack
- call TSSETSTACK ;Two 384 byte stacks
-
- call get_cmd_line ;Check for valid command line
- jc cmdline_err ;If invalid display message and exit
- call parkit ;else attempt to park heads
- jnc good_park ;If able to park say so
- mov dx,offset bad_park ;else print problem
- mov ah,09
- int 21h
- jmp term_it ;and quit with error code
- ;
- ; display installed message and exit
- ;
- good_park:
- mov dx,offset installed
- mov ah,09 ;Show that it's installed
- int 21h
- mov dx,offset miwa_miwa_parwa_stella
- mov ah,09
- int 21h ;and that it tinkles
- mov dx,offset TESSINITSTART
- mov bx,1070h ;No pop graphics, timer proc,
- ; background and main procs only
- mov ax,0A19h ;Alt-LeftShift-P
- ;will be hotkey for manual park.
-
- call TSDOINIT
- mov ax,4c00h ;Exit with no error code
- int 21h
-
- cmdline_err:
- mov dx,offset signon
- mov ah,09
- int 21h ;Display the signon message
- jmp term_it ;and quit with error code
-
- ;
- ;Non-resident data area
- ;
- ;Following are the message strings for the transient part of the program
- ;They do not go resident and are not available to the TSR portion
- ;
-
- signon label byte
- db 13,10,'TESSPARK.COM Version 1.0, Copyright (c) '
- db '1988, TesSeRact(tm) Development Team',13,10
- db 'All Rights Reserved',13,10,10
- db 'Based on Original Code provided by Jim Mischel:',13,10
- db ' AUTOPARK 1.0 Copyright (c) 1988, Jim Mischel',13,10,10
- db 'TSRPARK additions provided by Rick Housh:',13,10
- db ' Hotkey instant park, variable auto park intervals,',13,10
- db ' popup message (at DOS prompt), detection of park',13,10
- db ' failure on installation, and change of timer while',13,10
- db ' resident without removal and reinstallation.'
- db 13,10,10
- db 7,'Command line error. TSRPark NOT loaded.',7,13,10,10
- db 'Syntax: TSRPARK # (Where # is 1 - 9 [minutes] between parks)'
- db 13,10,'$'
- already_installed label byte
- db 13,10,'TSRPARK was already resident',13,10,7,'$'
- tsr_reset label byte
- db 13,10,'TSRPARK was resident and has been reset.',13,10,7,'$'
- installed label byte
- db 13,10,'TSRPARK installed. '
- auto_time label byte
- db 'Auto park every '
- minutes db ' '
- db ' minute(s).',13,10
- db 'Alt + Left Shift + "P" parks hard disks instantly',13,10,'$'
- miwa_miwa_parwa_stella label byte ;Or "miva" and "parva" if you prefer
- db 'A "tinkle" will sound when heads are parked',13,10,'$'
- bad_park label byte ;BAD PROBLEM, LOTS OF BELLS
- db 13,10,7,'Hard disk error. Unable to park hard disk.'
- db 13,10,7,'Terminating.',13,10,7,'$'
-
- _TEXT ends
-
- END