File Archive

 
Output of file : PARK.ASM contained in archive : YAPARK.ZIP

page 60,132
title PARK - A Head Parking Routine
name PARK

comment #
PARK V1.00
-------------------------------------------------------------------------------
NAME
park a head parking routine

SYNOPSIS
park

DESCRIPTION
park will move the read/write head to the landing zone, highest data
cyclinder plus one. park will do this for each hard disk installed.
It does this by getting the highest cylinder number from the current
drive parameters. The heads are seeked to the next cylinder. park
then to do this for the next hard disk. The process will continue
until an error is returned which means that there are no more valid
drives.

CAUTION
The landing zone must be one cylinder beyond the last data disk.

PROGRAMING NOTES
Assembled with Microsoft MASM V5.1 (not compatible with earlier
versions).

AUTHOR
Raymond Moon - 20 May 88

Copyright (c) 1987, MoonWare
ALL RIGHTS RESERVED

HISTORY
Version - Date Remarks
1.00 - 20 May 88 - Orginal

#

.MODEL small,FORTRAN
assume es:DGROUP
include C:\ASM\ASM.MAC ; Include Macro header file

;-----------------------------
; Define all string constants and included variables.

.CONST
LOGO db 'Hard Disk Head Parking Routine, V1.00'
db CR,LF,'Copyright (c) 1988, MoonWare'
db CR,LF,'ALL RIGHTS RESERVED',CR,CR,LF
LOGO_LEN equ $ - LOGO
STATUS db CR,LF,'Fixed Disk # '
DRIVE_NO db 30h
db ' is parked at cylinder '
CYL_NO db 4 dup (20h)
STATUS_LEN equ $ - STATUS
READ_ERR db 'ERROR: No Fixed Disk Appears To Be Installed.'
READ_ERR_LEN equ $ - READ_ERR
DOS_ERR db 'ERROR: Needs DOS 2.0+'
DOS_ERR_LEN equ $ - DOS_ERR
SEEK_ERR db 'ERROR: Unable to seek to landing zone.'
SEEK_ERR_LEN equ $ - SEEK_ERR
MARKER db '***** Raymond Moon - 20 May 1988 *****'

;-----------------------------
; Define all uninitialized variables.

.DATA?
COMM TEMP:byte:4 ; Temporary string for binary to ASCII conversion

;-----------------------------
; Define minimal stack of 256 bytes.

.STACK 100H

;------------------------------
; Define code segment

.CODE
MAIN proc far

;-----------------------------
; Initialize DS to point to DGROUP

mov ax,@data ; AX = DGROUP
mov ds,ax ; DS => DGROUP

;-----------------------------
; Determine DOS Version

mov ah,30h ; Request DOS version
int 21h ; Call DOS
cmp al,2 ; Is the major version 2 or greater?
jae MN1 ; Yes, continue
@WRITE DOS_ERR,STDERR ; No, tell user
push es ; Push return segment address
xor ax,ax ; Push return offset
push ax
ret ; Return to DOS int 20h

;-----------------------------
; Initialize ES to point to DGROUP.

MN1: mov ax,ds ; Get DGROUP
mov es,ax ; Set ES

;-----------------------------
; Print Logo

@WRITE LOGO,STDOUT

;-----------------------------
; Start the loop by getting the disk parameters.

MN2: mov dl,DRIVE_NO ; DL = drive number
add dl,50h ; Convert to drive designation
mov ah,8 ; Return current dirve parameters
int 13h ; Call Fixed Disk BIOS
jc MN5 ; Error, go take required action

;-----------------------------
; No error. CH plus upper two bits in CL contains the maximum
; cylinder number. Add one by incrementing CH.

inc ch ; Set cylinder number to next highest
call CONVERT ; Set CYL_NO
mov ah,0ch ; Seek
mov dl,DRIVE_NO ; DL = DRIVE_NO (ASCII)
add dl,50h ; DL = DRIVE_NO
int 13h ; Call Fixed Disk BIOS
jc MN3 ; Seek Error

;-----------------------------
; Tell User.

@WRITE STATUS,STDOUT ; User told.

;-----------------------------
; Increment DRIVE_NO and start again

inc DRIVE_NO ; DRIVE_NO = next drive designation
jmp MN2 ; Go again

;-----------------------------
; Seek Error. Tell User and terminate.

MN3: @WRITE SEEK_ERR,STDERR ; User told
MN4: mov ax,4c01h ; Terminate with error code
int 21h ; Call DOS

;-----------------------------
; Error on determining current drive parameters. See if it is the first
; hard disk. If so, tell user that no hard disks appear to be installed.
; If not the first, this is the end of the loop. Either way, terminate
; the program.

MN5: cmp DRIVE_NO,30h ; Is this the first?
ja MN6 ; No, to terminate
@WRITE READ_ERR,STDERR ; Tell user
jmp MN4 ; Error return

;-----------------------------
; Normal return.

MN6: mov ax,4c00h ; Indicate successful terminate
int 21h ; Call DOS

MAIN endp

;-----------------------------
; CONVERT converts the binary cylinder number in CH and the upper
; two bits of CL into an ASCII string in CYL_NO.

CONVERT proc

;----------------------------
; Blank the destination.

lea di,TEMP ; DI => TEMP
mov si,di ; Save it
mov ax,2020h ; AX = two blanks
stosw ; Blank first two chars
stosw ; Blank the last two chars
mov di,si ; DI => TEMP
mov al,ch ; AL = lower bits
mov ah,cl ; AH has hi two bits
rol ah,1 ; Shift bits into proper position
rol ah,1 ; AX = binary CYL_NO
and ax,3ffh ; Get rid of # of sectors
mov bx,10 ; Get conversion base
CT1: xor dx,dx ; Clear MSW
div bx ; AX = Quotient, DX = Remainder
xchg ax,dx ; Switch
or al,30h ; Convert to ASCII
stosb ; Store it in temp
or dx,dx ; Is quotient zero?
je CT2 ; Yes, break out of loop
mov ax,dx ; AX = quotient
jmp CT1 ; Continue conversion loop

;-----------------------------
; Temp has the ASCII string in reverse. Move it into CYL_NO.

CT2: add si,3 ; SI => last char of TEMP
lea di,CYL_NO ; DI => CYL_NO
mov bx,cx ; Save binary CYL_NO
mov cx,4 ; Move count
CT3: std ; Set direction flag
lodsb ; Get first
cld ; Clear direction flag
stosb ; Store it
loop CT3 ; Loop until done
mov cx,bx ; Restore binary CYL_NO

;-----------------------------
; Done, return.

ret
CONVERT endp
end MAIN