HDUTIL - AUTOPARK.ZIP - AUTOPARK.ASM

 
Output of file : AUTOPARK.ASM contained in archive : AUTOPARK.ZIP

PAGE 66,132
VECTORS SEGMENT AT 0H
ORG 8H*4
TOD_VECTOR LABEL DWORD ; CLOCK INTERRUPT
ORG 13H*4
DISK_VECTOR LABEL DWORD ; HARD DISK BIOS CALL
VECTORS ENDS
;
; THIS IS THE START OF THE LOCAL DATA AND EXECUTABLE CODE
;
CODE_SEG SEGMENT
ASSUME CS:CODE_SEG
ORG 100H
BEGIN: CALL PARK ; FIND OUT WHERE TO PARK
JMP INIT_VECTORS ;INITIALIZE VECTORS & ATTACH TO DOS
ROM_TOD_INT DD ? ; ADDRESSES FOR ROM ROUTINES
ROM_DISK_INT DD ?
TIMER_DELAY DW 546 ; DELAY BEFORE PARKING HEAD
DELAY DW ? ; CLOCK TICKS DURING DELAY
BUSY DB 0
CYLNUM0 DW 0
CYLNUM1 DW 0
;
; PARK THE HARD DISK HEAD AFTER DELAY WITHOUT USE
;
;
OUR_TOD_INT PROC NEAR
PUSHF
CALL ROM_TOD_INT ; GO TO OTHER CODE FIRST
PUSH AX
PUSH DS
MOV AX,CS ; SET DATA SEGMENT TO OURSELF
MOV DS,AX
ASSUME DS:CODE_SEG
DEC DELAY ; HAS DELAY ELAPSED?
JZ PARK_IT ; YUP
JG COUNT_DOWN ; NOPE
MOV DELAY,0 ; HEAD IS PARKED, RESET COUNTER TO 0
COUNT_DOWN: POP DS
POP AX
ASSUME DS:NOTHING
IRET
PARK_IT: ASSUME DS:CODE_SEG
PUSH AX
PUSH BX
PUSH CX
PUSH DX
TEST BUSY,80H ; IS DISK CODE BUSY?
JNZ IT_IS_BUSY ; OOPS, YES
CMP CYLNUM0,0 ; IS THERE A DISK 0?
JE NODISK0 ; NOPE
MOV AH,0CH ; SEEK
MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
MOV DL,80H ; DRIVE 0
MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
MOV CX,CYLNUM0 ; GET CYL NUMBER
XCHG CL,CH ; PUT LO ORDER IN CH
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
INC CL ; NOW SAY SECTOR 1
PUSHF
CALL ROM_DISK_INT ; MUST USE CALL SINCE INT 13H > HERE
NODISK0:
CMP CYLNUM1,0 ; IS THERE A DISK 1?
JE NODISK1 ; NO
MOV AH,0CH ; SEEK
MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
MOV DL,81H ; DRIVE 1
MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
MOV CX,CYLNUM1 ; GET CYL NUMBER
XCHG CL,CH ; PUT LO ORDER IN CH
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
INC CL ; NOW SAY SECTOR 1
PUSHF
CALL ROM_DISK_INT ; MUST USE CALL SINCE INT 13H > HERE
NODISK1:
POP DX
POP CX
POP BX
POP AX
JMP COUNT_DOWN
IT_IS_BUSY: CALL RESET ; DISK IS BUSY, WAIT ANOTHER 5 SEC
POP DX
POP CX
POP BX
POP AX
JMP COUNT_DOWN
OUR_TOD_INT ENDP
;
; THIS PROCEDURE RESETS THE TIMER COUNT TO ITS INITIAL VALUE
;
RESET PROC NEAR
PUSH AX
PUSH DS
MOV AX,CS
MOV DS,AX
ASSUME DS:CODE_SEG
MOV AX,TIMER_DELAY
MOV DELAY,AX
POP DS
POP AX
RET
RESET ENDP
;
;
; THIS PROCEDURE RESETS THE TIME-OUT COUNTER AND PASSES CONTROL
; TO THE BIOS DISK ROUTINES
;
CATCH_DISK PROC FAR
ASSUME DS:NOTHING
OR BUSY,80H ; MARK DISK BUSY
TEST DL,80H ; IS IT A HARD DISK CALL?
JZ NORESET ; NO
CALL RESET ; RESET THE TIME-OUT COUNTER
NORESET: PUSHF ; SIMULATE INTERRUPT
CALL ROM_DISK_INT ; DO BIOS STUFF
PUSHF ; REMEMBER FLAGS FROM DISK ROUTINE
AND BUSY,7FH ; MARK DISK NOT BUSY
POPF ; REMEMBER FLAGS FROM DISK ROUTINE
RET 2 ; THROW AWAY USER'S SAVED FLAGS
CATCH_DISK ENDP
;
; THIS PROCEDURE INITIALIZES THE INTERRUPT VECTORS
;
INIT_VECTORS PROC NEAR
ASSUME DS:VECTORS
MOV AX,VECTORS ; SET UP DATA SEGMENT FOR VECTORS
MOV DS,AX
CLI
MOV AX,WORD PTR TOD_VECTOR ; SAVE ADDRESSES OF BIOS ROUTINES
MOV WORD PTR ROM_TOD_INT,AX
MOV AX,WORD PTR TOD_VECTOR[2]
MOV WORD PTR ROM_TOD_INT[2],AX
MOV WORD PTR TOD_VECTOR,OFFSET OUR_TOD_INT
MOV WORD PTR TOD_VECTOR[2],CS
MOV AX,WORD PTR DISK_VECTOR
MOV WORD PTR ROM_DISK_INT,AX
MOV AX,WORD PTR DISK_VECTOR[2]
MOV WORD PTR ROM_DISK_INT[2],AX
MOV WORD PTR DISK_VECTOR,OFFSET CATCH_DISK
MOV WORD PTR DISK_VECTOR[2],CS
MOV AX,TIMER_DELAY ; SET DELAY TO STARTING COUNT
MOV DELAY,AX
STI ; ALLOW INTERRUPTS AGAIN
MOV DX,OFFSET INIT_VECTORS ; END OF RESIDENT PORTION
INT 27H ; TERMINATE BUT STAY RESIDENT
INIT_VECTORS ENDP
SUBTTL PARK -- PARK THE HEADS IN ORDER TO FIND OUT WHERE TO PARK
PAGE
PARK PROC
PUSH AX
PUSH CX
PUSH DX
PUSH ES
;
; MOVE DRIVE 0 AS FAR AS POSSIBLE IN STEPS OF 100 TRACKS
;
SEEK0100: MOV AH,0CH ; SEEK
MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
MOV DL,80H ; DRIVE 0
MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
MOV CX,CYLNUM0 ; GET CYLINDER NUMBER
ADD CX,100 ; INCREMENT BY 100
MOV CYLNUM0,CX ; PUT IT BACK
XCHG CL,CH ; PUT LO ORDER IN CH
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
INC CL ; NOW SAY SECTOR 1
INT 13H
MOV AH,01H ; CHECK STATUS
MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
MOV DL,80H ; DRIVE 0
MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
MOV CX,1 ; CYL 0 SECTOR 1
INT 13H
OR AL,AL
JZ SEEK0100
MOV AX,CYLNUM0
SUB AX,100
MOV CYLNUM0,AX
;
; MOVE DRIVE 0 AS FAR AS POSSIBLE IN STEPS OF 10 TRACKS
;
SEEK010: MOV AH,0CH ; SEEK
MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
MOV DL,80H ; DRIVE 0
MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
MOV CX,CYLNUM0 ; GET CYLINDER NUMBER
ADD CX,10 ; INCREMENT BY 10
MOV CYLNUM0,CX ; PUT IT BACK
XCHG CL,CH ; PUT LO ORDER IN CH
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
INC CL ; NOW SAY SECTOR 1
INT 13H
MOV AH,01H ; CHECK STATUS
MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
MOV DL,80H ; DRIVE 0
MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
MOV CX,1 ; CYL 0 SECTOR 1
INT 13H
OR AL,AL
JZ SEEK010
MOV AX,CYLNUM0
SUB AX,10
MOV CYLNUM0,AX
;
; MOVE DRIVE 0 AS FAR AS POSSIBLE IN STEPS OF 1 TRACK
;
SEEK01: MOV AH,0CH ; SEEK
MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
MOV DL,80H ; DRIVE 0
MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
INC CYLNUM0 ; INCREMENT CYLINDER NUM
MOV CX,CYLNUM0 ; GET CYL NUMBER
XCHG CL,CH ; PUT LO ORDER IN CH
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
INC CL ; NOW SAY SECTOR 1
INT 13H
MOV AH,01H ; CHECK STATUS
MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
MOV DL,80H ; DRIVE 0
MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
MOV CX,1 ; CYL 0 SECTOR 1
INT 13H
OR AL,AL
JZ SEEK01
DEC CYLNUM0
CMP CYLNUM0,0
JE NODRIVE0
MOV AX,CYLNUM0
PUSH DS
POP ES
LEA DX,CYLDEC0
CALL DECIMAL_CONVERT
MOV AH,9
LEA DX,CYLMSG0
INT 21H
NODRIVE0:
;
; MOVE DRIVE 1 AS FAR AS POSSIBLE IN STEPS OF 100 TRACKS
;
SEEK1100: MOV AH,0CH ; SEEK
MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
MOV DL,81H ; DRIVE 1
MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
MOV CX,CYLNUM1 ; GET CYLINDER NUMBER
ADD CX,100 ; INCREMENT BY 100
MOV CYLNUM1,CX ; PUT IT BACK
XCHG CL,CH ; PUT LO ORDER IN CH
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
INC CL ; NOW SAY SECTOR 1
INT 13H
MOV AH,01H ; CHECK STATUS
MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
MOV DL,81H ; DRIVE 1
MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
MOV CX,1 ; CYL 0 SECTOR 1
INT 13H
OR AL,AL
JZ SEEK1100
MOV AX,CYLNUM1
SUB AX,100
MOV CYLNUM1,AX
;
; MOVE DRIVE 1 AS FAR AS POSSIBLE IN STEPS OF 10 TRACKS
;
SEEK110: MOV AH,0CH ; SEEK
MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
MOV DL,81H ; DRIVE 1
MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
MOV CX,CYLNUM1 ; GET CYLINDER NUMBER
ADD CX,10 ; INCREMENT BY 10
MOV CYLNUM1,CX ; PUT IT BACK
XCHG CL,CH ; PUT LO ORDER IN CH
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
INC CL ; NOW SAY SECTOR 1
INT 13H
MOV AH,01H ; CHECK STATUS
MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
MOV DL,81H ; DRIVE 1
MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
MOV CX,1 ; CYL 0 SECTOR 1
INT 13H
OR AL,AL
JZ SEEK110
MOV AX,CYLNUM1
SUB AX,10
MOV CYLNUM1,AX
;
; MOVE DRIVE 0 AS FAR AS POSSIBLE IN STEPS OF 1 TRACK
;
SEEK1: MOV AH,0CH ; SEEK
MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
MOV DL,81H ; DRIVE 1
MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
INC CYLNUM1 ; INCREMENT CYLINDER NUM
MOV CX,CYLNUM1 ; GET CYL NUMBER
XCHG CL,CH ; PUT LO ORDER IN CH
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
SAL CL,1 ; PUT HI IN TOP OF CL
INC CL ; NOW SAY SECTOR 1
INT 13H
MOV AH,01H ; CHECK STATUS
MOV AL,1 ; GOTTA HAVE A SECTOR COUNT
MOV DL,81H ; DRIVE 1
MOV DH,0 ; GOTTA HAVE A HEAD NUMBER
MOV CX,1 ; CYL 0 SECTOR 1
INT 13H
OR AL,AL
JZ SEEK1
DEC CYLNUM1
CMP CYLNUM1,0
JE NODRIVE1
MOV AX,CYLNUM1
PUSH DS
POP ES
LEA DX,CYLDEC1
CALL DECIMAL_CONVERT
MOV AH,9
LEA DX,CYLMSG1
INT 21H
NODRIVE1:
MOV AH,9
LEA DX,BLANKLINE
INT 21H
POP ES
POP DX
POP CX
POP AX
RET
CYLMSG0 DB 0AH,0DH,"Hard disk 0 parking place is cylinder"
CYLDEC0 DB " .$"
CYLMSG1 DB 0AH,0DH,"Hard disk 1 parking place is cylinder"
CYLDEC1 DB " .$"
BLANKLINE DB 0AH,0DH,"$"
PARK ENDP
SUBTTL DECIMAL CONVERT (TO ASCII STRING FOR DISPLAY)
PAGE
;
; DECIMAL_CONVERT IS ENTERED WITH A NUMBER IN AX AND ES:DX POINTING TO
; A FIVE-BYTE FIELD. IT CONVERTS THE NUMBER INTO A FIVE-BYTE INTEGER
; FROM 0 TO 65535 AND PLACES IT IN ASCII IN THE FIVE-BYTE FIELD.
; IT ALTERS NO REGISTERS AT ALL.
;
DECIMAL_CONVERT PROC
PUSH BX
PUSH DX
PUSH DI
ASSUME ES:NOTHING
;
; DIVIDE BY TEN TO GET UNITS AS REMAINDER
;
MOV DI,DX
MOV BX,10 ; DIVISOR
MOV DX,0 ; HIGH ORDER MUST BE ZERO
DIV BX ; DIVIDE -- REMAINDER IN DX
ADD DL,"0" ; MAKE REMAINDER ASCII
MOV BYTE PTR ES:[DI+4],DL ; PUT BYTE IN DESTINATION
;
; DIVIDE AGAIN FOR TENS
;
MOV DX,0 ; HIGH ORDER MUST BE ZERO
DIV BX
ADD DL,"0"
MOV BYTE PTR ES:[DI+3],DL
;
; DIVIDE AGAIN FOR HUNDREDS
;
MOV DX,0
DIV BX
ADD DL,"0"
MOV BYTE PTR ES:[DI+2],DL
;
; THOUSANDS
;
MOV DX,0
DIV BX
ADD DL,"0"
MOV BYTE PTR ES:[DI+1],DL
;
; TEN-THOUSANDS
;
MOV DX,0
DIV BX
ADD DL,"0"
MOV BYTE PTR ES:[DI],DL
;
; GET RID OF LEADING ZEROS
;
CMP BYTE PTR ES:[DI],"0"
JNE DECIMAL_DONE
MOV BYTE PTR ES:[DI]," "
CMP BYTE PTR ES:[DI+1],"0"
JNE DECIMAL_DONE
MOV BYTE PTR ES:[DI+1]," "
CMP BYTE PTR ES:[DI+2],"0"
JNE DECIMAL_DONE
MOV BYTE PTR ES:[DI+2]," "
CMP BYTE PTR ES:[DI+3],"0"
JNE DECIMAL_DONE
MOV BYTE PTR ES:[DI+3]," "
DECIMAL_DONE:
POP DI
POP DX
POP BX
RET
DECIMAL_CONVERT ENDP
CODE_SEG ENDS
END BEGIN