ASSEMBLY - AT110.ZIP - AT110.ASM

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

PAGE 60,132
.286c
DOSTEST = 0
ENDER MACRO
; END INITIALIZE
END
ENDM
VERSION MACRO
DB 'COPYRIGHT (C) JIM BRACKING, 1984,1985,1986 '
DB 'AUTHOR - JIM BRACKING '
DB 'SAN JOSE, CA '
DB 'VERSION 1.10 01/10/85 '
ENDM
TRACE MACRO TT
; **********************************************************************
; PUSH AX ;SAVE AX
; MOV AX,TT ;TRACE ENTRY TYPE
; CALL TRACE_IT ;TRACE IT
; POP AX ;RESTORE AX
; **********************************************************************
ENDM
TITLE HARD DISK BIOS ROUTINE FOR THE IBM AT
; **********************************************************************
; * *
; * MODULE NAME: AT *
; * *
; * VERSION 1.10 *
; * *
; * DECSRIPTION: THIS PROGRAM RECEIVES CONTROL DURING IPL. *
; * DURING INITIALIZATION THIS PROGRAM WILL *
; * PERFORM THE FOLLOWING FUNCTIONS. *
; * *
; * 1. REVECTOR INT 13H TO INT 40H. *
; * 2. POINT INT 13H TO THIS PROGRAM. *
; * 3. DETERMINE HOW MANY HARD DISKS ARE *
; * INSTALLED AND RESET THEM. *
; * 4. SET THE HARD DISK IPL FLAG IN CMOS BYTE 0E *
; * IF RESET FOR HARD DISK 0 FAILS. *
; * 5. REPLACE INT 19H (BOOTSTRAP LOADER). *
; * *
; * *
; * INPUTS: *
; * *
; * INITIALIZATION - CMOS RAM BYTE 34 FOR DRIVE 0 *
; * CMOS RAM BYTE 35 FOR DRIVE 1 *
; * *
; * *
; * INT 13H - AH = DISK FUNCTION *
; * AL = NUMBER OF SECTORS *
; * *
; * DH = HEAD NUMBER *
; * DL = DRIVE NUMBER (80H - 87H) *
; * *
; * CH = CYLINDER NUMBER *
; * CL = SECTOR NUMBER ( CCSSSSSS ) *
; * NOTE - BITS 0-1 ARE FOR CYL NUMBER *
; * BITS 2-7 ARE FOR SECTOR NUMBER *
; * *
; * ES:BX = BUFFER ADDRESS *
; * *
; * NOTE: THIS INTERRUPT PROVIDES A COMPATIBLE IBM *
; * INTERFACE TO THE HARD DISK. ADDITIONALLY *
; * THE CALLING PROGRAM MAY TAKE ADVANTAGE OF *
; * THE SPECIAL COMMANDS LISTED BELOW. *
; * *
; * *
; * OUTPUTS: *
; * *
; * INITIALIZATION - INT VECTORS ARE CHANGED *
; * *
; * *
; * INT 13H - AH = STATUS OF CURRENT OPERATION *
; * CY = 0 SUCESSFULL OPERATION *
; * CY = 1 UNSUCESSFULL OPERATION *
; * *
; * *
; * FUNCTION CODES (HEX) *
; * *
; * IBM COMMANDS *
; * *
; * 00 - RESET DISK *
; * 01 - PUT STATUS OF LAST FUNCTION INTO AL *
; * 02 - READ SECTOR *
; * 03 - WRITE SECTOR *
; * 04 - VERIFY SECTOR *
; * 05 - FORMAT TRACK *
; * 06 - UNUSED *
; * 07 - UNUSED *
; * 08 - RETURN THE CURRENT DRIVE PARAMETERS *
; * 09 - INITIALIZE DRIVE PAIR CHARACTERISTICS *
; * INT 41H POINTS TO DRIVE 0 PARAMETERS *
; * INT 46H POINTS TO DRIVE 1 PARAMETERS *
; * 0A - READ LONG *
; * 0B - WRITE LONG *
; * 0C - SEEK *
; * 0D - ALTERNATE DISK RESET *
; * 0E - UNUSED *
; * 0F - UNUSED *
; * 10 - TEST DRIVE READY *
; * 11 - RECALIBRATE *
; * 12 - UNUSED *
; * 13 - UNUSED *
; * 14 - CONTROLLER INTERNAL DIAG. *
; * 15 - READ DASD TYPE *
; * *
; * *
; * SPECIAL COMMANDS *
; * *
; * *
; **********************************************************************
; * *
; * CHANGE LOG: *
; * 01/22/85 - BSEC_ER REFLECTED AN ERROR CODE OF 0BH INSTEAD OF 0AH *
; * 04/23/86 - CHANGED USAGE OF CMOS RAM TO BYTE 34 FOR DRIVE 0 AND *
; * BYTE 35 FOR DRIVE 1. EXPANDED THE DRIVE TABLE TO 45 *
; * DRIVE TYPES. *
; **********************************************************************
;
; **********************************************************************
; * WORKAREAS *
; **********************************************************************
DUMMY SEGMENT AT 0
ORG 13H*4 ;DISK INTERRUPT VECTOR
INT_13H LABEL DWORD
ORG 40H*4 ;NEW DISKETTE INTERRUPT VECTOR
INT_40H LABEL DWORD
ORG 41H*4 ;HARD DISK PARAMETER TABLE - DRIVE 0
INT_41H LABEL DWORD
ORG 46H*4 ;HARD DISK PARAMETER TABLE - DRIVE 1
INT_46H LABEL DWORD
ORG 64H*4 ;TRACE ROUTINE VECTORS
INT_64H LABEL DWORD
ORG 67H*4 ;TRACE ROUTINE VECTORS
INT_67H LABEL DWORD
ORG 76H*4 ;HARD DISK INTERRUPT VECTOR
INT_76H LABEL DWORD
ORG 7C00H ;BOOTSTRAP LOAD VECTOR
DUMMY ENDS
;
DATA SEGMENT AT 40H
ORG 42H ;COMMAND BLOCK
HD_DCB LABEL BYTE
HD_CMD DB ? ;CONTROLLER COMMAND
HD_CYLHI DB ? ;CYLINDER HIGH
HD_CYLLO DB ? ;CYLINDER LOW
HD_HEAD DB ? ;HEAD NUMBER
HD_SNUM DB ? ;SECTOR NUMBER
HD_SCNT DB ? ;SECTOR COUNT
ORG 06CH ;TIMMER LOW WORD
TIMER_LOW DW ?
ORG 074H
HD_STATUS DB ? ;HARD DISK STATUS BYTE
HD_NUM DB ? ;NUMBER OF HARD DISK DRIVES
HD_DRIVE DB ? ;HARD DISK DRIVE NUMBER
HD_COMP DB ? ;COMPATABILITY FLAG
;
; BITS 7-4 FOR DRIVE0 AND BITS 3-0 FOR DRIVE 1
;
HD_AT EQU 00H ;NATIVE AT MODE
HD_PC EQU 0FH ;PC MODE
ORG 08CH
HD_STAT DB ? ;STATUS REGISTER
HD_ERR DB ? ;ERROR REGISTER
HD_INT_FLAG DB ? ;HARD DISK INTERRUPT FLAG
;
DATA ENDS
; **********************************************************************
; * ERROR EQUATES *
; **********************************************************************
CMD_ER EQU 01H ;BAD COMMAND
ADMRK_ER EQU 02H ;ADDRESS MARK NOT FOUND
NRF_ER EQU 04H ;NO RECORD FOUND
RESET_ER EQU 05H ;RESET ERROR
INIT_ER EQU 07H ;DRIVE INITIALIZATION ERROR
DMA_ER EQU 09H ;DMA ACCROSS 64K BOUNDRY
BSEC_ER EQU 0AH ;BAD SECTOR FLAG DETECTED
ECC_ER EQU 10H ;BAD ECC ON READ
DATA_ER EQU 11H ;CORRECTED ECC ERROR
CTLR_ER EQU 20H ;CONTROLLER ERROR
SEEK_ER EQU 40H ;SEEK ERROR
TIME_ER EQU 80H ;DISK TIME OUT
NRDY_ER EQU 0AAH ;DRIVE NOT READY
UNDEF_ER EQU 0BBH ;UNDEFINED ERROR
WRFLT_ER EQU 0CCH ;WRITE FAULT
NO_ER EQU 0E0H ;ERROR REG = 0
SENSE_ER EQU 0FFH ;SENSE ERROR
;
;
; **********************************************************************
; * CMOS RAM PORT EQUATES *

; **********************************************************************
CMOS_ADP EQU 70H ;CMOS ADDRESS PORT
CMOS_RW EQU 71H ;CMOS READ/WRITE PORT
CMOS_D0 EQU 34H ;DRIVE 0 CMOS BYTE
CMOS_D1 EQU 35H ;DRIVE 1 CMOS BYTE
CMOS_IBM EQU 12H ;IBM'S HARD DISK CONFIGURATION
CMOS_DIAG EQU 0EH ;CMOS DIAG BYTE
HD_IPL EQU 08H ;IF RESET THIS ALLOWS IPL FROM HARD DISK
; **********************************************************************
; * INTERRUPT CONTROLLER PORT EQUATES *
; **********************************************************************
CTLR1_PORT EQU 20H ;INTERRUPT CONTROL PORT
CTLR1_MASK EQU 21H ;INTERRUPT MASK PORT
CTLR2_PORT EQU 0A0H ;INTERRUPT CONTROL PORT
CTLR2_MASK EQU 0A1H ;INTERRUPT MASK PORT
IRQ_0 EQU 01H ;TIMMER INTERRUPT
IRQ_2 EQU 04H ;CTLR2 INTERRUPTS
IRQ_14 EQU 40H ;HARD DISK INTERRUPT
; **********************************************************************
; * CONTROLLER PORT EQUATES *
; **********************************************************************
HD_P0 EQU 01F0H ;DATA/DATA
HD_P1 EQU 01F1H ;ERROR/WRITE PRE-COMP
HD_P2 EQU 01F2H ;SEC CNT/SEC CNT
HD_P3 EQU 01F3H ;SEC NUM/SEC NUM
HD_P4 EQU 01F4H ;CYL LO/CYL LO
HD_P5 EQU 01F5H ;CYL HI/CYL HI
HD_P6 EQU 01F6H ;DRIVE,HEAD/DRIVE,HEAD
HD_P7 EQU 01F7H ;STATUS/COMMAND
HD_REG EQU 03F6H ;USED FOR CTLR RESET AND EXTRA HEAD
HD_RESET EQU 04H ;CTLR RESET
HD_EXHD EQU 08H ;EXTRA HEAD OPTION
HD_REQ EQU 0A0H ;REQUIRED FOR DRIVE/HEAD REGISTER
; **********************************************************************
; * STATUS REGISTER EQUATES *
; **********************************************************************
S_BUSY EQU 10000000B ;CONTROLLER BUSY
S_DRDY EQU 01000000B ;DRIVE READY
S_WRFLT EQU 00100000B ;WRITE FAULT
S_SEKCMP EQU 00010000B ;SEEK COMPLETE
S_DRQ EQU 00001000B ;DATA REQUEST
S_CORECC EQU 00000100B ;ECC CORRECTED DATA
S_INDEX EQU 00000010B ;INDEX PAULSE
S_ERROR EQU 00000001B ;E R R O R
; **********************************************************************
; * ERROR REGISTER EQUATES *
; **********************************************************************
;
; AFTER CTLR_DIAG_CMD
;
E_NOER EQU 01H ;NO ERRORS
E_CTLR EQU 02H ;CONTROLLER ERROR
E_SBUFF EQU 03H ;SECTOR BUFFER ERROR
E_ECCD EQU 04H ;ECC DEVIVE ERROR
E_CPROC EQU 05H ;CONTROL PROCESSOR ERROR
;
; AFTER EXECUTING COMMANDS
;
E_ADMARK EQU 00000001B ;ADDRESS MARK NOT FOUND
E_TRK0 EQU 00000010H ;NO TRACK ZERO FOUND
E_CMD EQU 00000100H ;COMMAND ABORTED
E_SPARE1 EQU 00001000H ;NOT USED
E_ID EQU 00010000H ;ID NOT FOUND
E_SPARE2 EQU 00100000H ;NOT USED
E_UNCORR EQU 01000000H ;UNCORRECTABLE DATA ERROR
E_BADSEC EQU 10000000H ;BAD SECTOR MARK DETECTED
;
CTLR1_PORT EQU 20H ;INTERRUPT CONTROL PORT
CTLR1_MASK EQU 21H ;INTERRUPT MASK PORT
CTLR2_PORT EQU 0A0H ;INTERRUPT CONTROL PORT
CTLR2_MASK EQU 0A1H ;INTERRUPT MASK PORT
;
; **********************************************************************
; * CONTROLLER COMMANDS *
; **********************************************************************
RECAL_CMD EQU 10H ;RECALIBRATE
SEEK_CMD EQU 70H ;SEEK
READ_CMD EQU 20H ;READ DATA
READ_LONG_CMD EQU 22H ;READ DATA + 4 BYTES ECC
WRITE_LONG_CMD EQU 32H ;WRITE DATA + 4 BYTES ECC
WRITE_CMD EQU 30H ;WRITE DATA
FORMAT_TRK_CMD EQU 50H ;FORMAT TRACK
READ_VERIFY_CMD EQU 40H ;READ VERIFY COMMAND
CTLR_DIAG_CMD EQU 90H ;CONTROLLER DIAGNOSTIC
WR_PARM_CMD EQU 91H ;ASSIGN DISK PARAMETERS
; **********************************************************************
; * TIME OUT DELAYS IN SECONDS *
; **********************************************************************
STATUS_DELAY EQU 01*18 ;APPROX 01 SECONDS
CTLR_DELAY EQU 01*18 ;APPROX 01 SECONDS
IRQ_DELAY EQU 60*18 ;APPROX 60 SECONDS
DRQ_DELAY EQU 01*18 ;APPROX 01 SECONDS
READY_DELAY EQU 45*18 ;APPROX 45 SECONDS
SEEK_DELAY EQU 02*18 ;APPROX 02 SECONDS
; **********************************************************************
; * SPECIAL FUNCTIONS *
; **********************************************************************
SPC_RESET_CTLR EQU 80H ;SENSE STATUS
SPC_REQ_PARM EQU 81H ;REQUEST DRIVE PARMS
; **********************************************************************
; * *
; * INITIALIZATION *
; * *
; **********************************************************************
CODE SEGMENT
ASSUME CS:CODE
; **********************************************************************
IF DOSTEST
ORG 100H ;*************************************
ELSE
ORG 00H
DB 055H
DB 0AAH
DB 80H
ENDIF
INITIALIZE PROC FAR
JMP INIT_00 ;AROUND COPYRIGHT NOTICE
VERSION
INIT_00:
STI ;ENABLE INTERRUPTS
XOR AX,AX ;CLEAR AX
MOV ES,AX ;INIT DS REG
ASSUME ES:DUMMY
CALL SETUP_DS ;ESTABLISH SEGMENT
ASSUME DS:DATA
; **********************************************************************
; * *
; * MAKE SURE THE IBM DISK BIOS DOES NOT GET INVOKED *
; * *
; **********************************************************************
MOV AL,CMOS_IBM ;READ
OUT CMOS_ADP,AL ; THE IBM
JMP $+2 ; HARD DISK
IN AL,CMOS_RW ; CONFIGURATION BYTE
OR AL,AL ;IBM DISKS CONFIGURED??
JZ INIT_02 ;NO - OK TO CONTINUE
LEA BP,CS:MSG7 ;ERROR MESSAGE
MOV CX,MSG7_L ;MSG LENGTH
CALL WRITE_MSG ;DISPLAY THE MESSAGE
JMP INIT_EXIT ;AND EXIT
INIT_02:
CLI ;DISABLE INTERRUPTS
IN AL,CTLR1_MASK ;ENABLE
AND AL,0FFH-IRQ_2 ; INTERRUPT
OUT CTLR1_MASK,AL ; CTLR
IN AL,CTLR2_MASK ;ENABLE THE
AND AL,0FFH-IRQ_14 ; HARD DISK
OUT CTLR2_MASK,AL ; INTERRUPT
MOV HD_COMP,00H ;DEFAULT MODE TO IBM/AT
MOV HD_STATUS,0 ;CLEAR STATUS
MOV HD_NUM,0 ;ZERO NUMBER OF HARD DISKS
LEA AX,DR_TABLE ;ESTABLISH
MOV WORD PTR INT_41H,AX ; DEFAULT DRIVE
MOV WORD PTR INT_41H+2,CS ; PARAMETERS
MOV WORD PTR INT_46H,AX ; FOR DRIVE
MOV WORD PTR INT_46H+2,CS ; 0 & 1
; **********************************************************************
IF DOSTEST
JMP INIT_05 ;JIM ***************************
ELSE
MOV AX,WORD PTR INT_13H ;RELOCATE
MOV WORD PTR INT_40H,AX ; DISKETTE ROUTINE
MOV AX,WORD PTR INT_13H+2 ; TO INTERRUPT
MOV WORD PTR INT_40H+2,AX ; VECTOR 40H
ENDIF
INIT_05:
LEA AX,HD_INT ;ESTABLISH
MOV WORD PTR INT_76H,AX ; NEW VECTORS
MOV WORD PTR INT_76H+2,CS ; FOR INT 0DH
;
LEA AX,HD_IO ;ESTABLISH
IF DOSTEST
MOV WORD PTR ES:104EH,AX ;INPUT IT WHERE DOS3 SAVED IT
MOV WORD PTR ES:1050H,CS
ELSE
MOV WORD PTR INT_13H,AX ; NEW VECTORS
MOV WORD PTR INT_13H+2,CS ; FOR INT 13H
ENDIF
;
STI ;ENABLE INTERRUPTS
MOV AL,CMOS_DIAG ;GET THE
OUT CMOS_ADP,AL ; STATUS OF
JMP $+2 ; THE CMOS
IN AL,CMOS_RW ; RAM
MOV AH,AL ;SAVE IT IN AH
TEST AL,0CH ;CMOS RAM VALID??
JZ INIT_10 ;YES
JMP INIT_EXIT ;OTHERWISE EXIT
INIT_10:
AND AH,0FFH-HD_IPL ;ALLOW
MOV AL,CMOS_DIAG ; IPL'S
OUT CMOS_ADP,AL ; FROM
JMP $+2 ; THE
MOV AL,AH ; HARD
OUT CMOS_RW,AL ; DISK
JMP $+2 ;DELAY A LITTLE
MOV AL,CMOS_D0 ;READ
OUT CMOS_ADP,AL ; DRIVE
JMP $+2 ; ZERO
IN AL,CMOS_RW ; CONFIGURATION BYTE
OR AL,AL ;INSTALLED??
JNZ INIT_15 ;YES
LEA BP,CS:MSG1 ;ERROR MESSAGE
MOV CX,MSG1_L ;MSG LENGTH
CALL WRITE_MSG ;DISPLAY THE MESSAGE
JMP INIT_EXIT ;AND EXIT
INIT_15:
CLI ;DISABLE INTERRUPTS
XOR AH,AH ;CLEAR AH
DEC AL ;RELEITIVE TO ZERO
MOV CL,4 ; DRIVE 0
SHL AX,CL ;MULTIPLY BY 16
LEA DX,DR_TABLE ;POINT TO
ADD DX,AX ; DRIVE TABLE ENTRY
MOV WORD PTR INT_41H,DX ;UPDATE DRIVE 0 INDEX
MOV HD_NUM,01H ;ONE HARD DISK
MOV AL,CMOS_D1 ;READ
OUT CMOS_ADP,AL ; DRIVE
JMP $+2 ; ONE
IN AL,CMOS_RW ; CONFIGURATION BYTE
OR AL,AL ;INSTALLED??
JZ INIT_16 ;NO
XOR AH,AH ;CLEAR AH
DEC AL ;RELEITIVE TO ZERO
MOV CL,4 ; DRIVE 0
SHL AX,CL ;MULTIPLY BY 16
LEA DX,DR_TABLE ;POINT TO
ADD DX,AX ; DRIVE TABLE ENTRY
MOV WORD PTR INT_46H,DX ;UPDATE DRIVE 1 INDEX
INIT_16:
STI ;ENABLE INTERRUPTS
; **********************************************************************
; * MAKE SURE CONTROLLER IS WORKING *
; **********************************************************************
INIT_17:
CLI ;DISABLE INTERRUPTS
IN AL,CTLR1_MASK ;ENABLE
AND AL,0FFH-IRQ_0 ; THE TIMMER
OUT CTLR1_MASK,AL ; INTERRUPT
STI ;ENABLE INTERRUPTS
MOV HD_NUM,01H ;ONE HARD DISK
MOV AH,80H ;RESET CONTROLLER
MOV DX,0080H ;NEED A VALID DISK
INT 13H ;EXECUTE IT
JC INIT_19 ;RESET FAILED
MOV AH,14H ;CONTROLLER DIAGNOSTIC
INT 13H ;EXECUTE IT
JNC INIT_20 ;CONTROLLER IS WORKING
INIT_19:
LEA BP,CS:MSG2 ;ERROR MESSAGE
MOV CX,MSG2_L ;MSG LENGTH
CALL WRITE_MSG ;DISPLAY THE MESSAGE
CALL NO_IPL ;NO HARD DISK IPL'S
JMP INIT_EXIT ;AND EXIT
; **********************************************************************
; * NOW CHECK DRIVE 0 *
; **********************************************************************
INIT_20:
MOV DX,0080H ;DRIVE 0
CALL TD_READY ;TEST DRIVE READY
JC INIT_22 ;DRIVE NOT READY
CALL RS_DRIVE ;CHECK OUT THE DRIVE
JC INIT_25 ;DRIVE FAILED RESET
JMP INIT_30 ;CONTINUE
INIT_22:
LEA BP,CS:MSG3 ;ERROR MESSAGE
MOV CX,MSG3_L ;MSG LENGTH
CALL WRITE_MSG ;DISPLAY THE MESSAGE
CALL NO_IPL ;NO HARD DISK IPL'S
JMP INIT_EXIT ;AND EXIT
INIT_25:
LEA BP,CS:MSG5 ;ERROR MESSAGE
MOV CX,MSG5_L ;MSG LENGTH
CALL WRITE_MSG ;DISPLAY THE MESSAGE
CALL NO_IPL ;NO HARD DISK IPL'S
JMP INIT_EXIT ;AND EXIT
; **********************************************************************
; * NOW CHECK DRIVE 1 *
; **********************************************************************
INIT_30:
MOV AL,CMOS_D1 ;READ
OUT CMOS_ADP,AL ; DRIVE
JMP $+2 ; ONE
IN AL,CMOS_RW ; CONFIGURATION BYTE
OR AL,AL ;DRIVE ONE CONFIGURED??
JZ INIT_EXIT ;NO - ALL DONE
INC HD_NUM ;TWO HARD DISKS
MOV DX,0081H ;DRIVE 1
CALL TD_READY ;DRIVE READY??
JC INIT_35 ;DRIVE NOT READY
CALL RS_DRIVE ;CHECK OUT THE DRIVE
JC INIT_40 ;DRIVE FAILED
JMP INIT_EXIT ;INITIALIZATION COMPLETE
INIT_35:
LEA BP,CS:MSG4 ;ERROR MESSAGE
MOV CX,MSG4_L ;MSG LENGTH
CALL WRITE_MSG ;DISPLAY THE MESSAGE
DEC HD_NUM ;REMOVE THIS DISK
JMP INIT_EXIT ;EXIT
INIT_40:
LEA BP,CS:MSG6 ;ERROR MESSAGE
MOV CX,MSG6_L ;MSG LENGTH
CALL WRITE_MSG ;DISPLAY THE MESSAGE
DEC HD_NUM ;REMOVE THIS DISK
; **********************************************************************
; * CLEAN UP AND EXIT *
; **********************************************************************
INIT_EXIT:
CMP HD_NUM,00H ;AND DRIVES INSTALLED??
JE INIT_EXIT_20 ;NO
MOV AL,HD_COMP ;COMPATABILITY FLAG
AND AL,0F0H ;DRIVE 0 ONLY
OR AL,AL ;AT MODE??
JZ INIT_EXIT_10 ;YES - SKIP MSG
LEA BP,CS:MSG8 ;MESSAGE ADDRESS
MOV CX,MSG8_L ;MSG LENGTH
CALL WRITE_MSG ;DISPLAY THE MESSAGE
INIT_EXIT_10:
MOV AL,HD_COMP ;COMPATABILITY FLAG
AND AL,0FH ;DRIVE 1 ONLY
OR AL,AL ;AT MODE??
JZ INIT_EXIT_20 ;YES - SKIP MSG
LEA BP,CS:MSG9 ;MESSAGE ADDRESS
MOV CX,MSG9_L ;MSG LENGTH
CALL WRITE_MSG ;DISPLAY THE MESSAGE
INIT_EXIT_20:
IF DOSTEST
MOV DX,0100H ;ALLOW FOR A 4K PROGRAM
XOR AX,AX
MOV AH,31H
INT 21H
RET
;******************************************************
ELSE
RET
ENDIF
; **********************************************************************
;
MSG1 DB 'NO HARD DISKS INSTALLED - RUN THE ATCONFIG PROGRAM',0DH,0AH
MSG1_L EQU $-MSG1
MSG2 DB 'HARD DISK CONTROLLER FAILURE - 1782',0DH,0AH
MSG2_L EQU $-MSG2
MSG3 DB 'HARD DISK C: NOT RESPONDING - 1780',0DH,0AH
MSG3_L EQU $-MSG3
MSG4 DB 'HARD DISK D: NOT RESPONDING - 1781',0DH,0AH
MSG4_L EQU $-MSG4
MSG5 DB 'HARD DISK C: FAILURE - 1790',0DH,0AH
MSG5_L EQU $-MSG5
MSG6 DB 'HARD DISK D: FAILURE - 1791',0DH,0AH
MSG6_L EQU $-MSG6
MSG7 DB 'THE HARD DISK(S) CAN ONLY BE CONFIGURED USING THE '
DB 'CONFIGURATION PROGRAM',0DH,0AH
DB 'RUN THE IBM SETUP PROGRAM TO DE-INSTALL THE HARD DISK(S)'
DB 0DH,0AH
MSG7_L EQU $-MSG7
MSG8 DB 'DRIVE C: RUNNING IN IBM/PC COMPATABILITY MODE',0DH,0AH
MSG8_L EQU $-MSG8
MSG9 DB 'DRIVE D: RUNNING IN IBM/PC COMPATABILITY MODE',0DH,0AH
MSG9_L EQU $-MSG9

INCLUDE DRIVETBL.ASM
INITIALIZE ENDP
; **********************************************************************
; * *
; * WRITE MESSAGE *
; * BP = MESSAGE ADDRESS *
; * CX = MESSAGE LENGTH *
; * *
; **********************************************************************
WRITE_MSG PROC
PUSH ES ;SAVE DS
PUSH CS ;ESTABLISH
POP ES ; SEGMENT
XOR BH,BH ;PAGE ZERO
PUSH CX ;SAVE LENGTH
PUSH BP ;SAVE MSG ADDRESS
MOV AH,03H ;READ CURSOR POSITION
INT 10H ;DO IT
POP BP ;RESTORE BP
POP CX ;RESTORE CX
XOR BH,BH ;PAGE ZERO
MOV BL,07H ;NORMAL INTENSITY
MOV AH,19 ;WRITE STRING FUNCTION
MOV AL,01H ;SUB FUNCTION
INT 10H ;DISPLAY THE MESSAGE
POP ES ;RESTORE DS
RET ;AND RETURN
WRITE_MSG ENDP
; **********************************************************************
; * *
; * INDICATE NO HARD DISK IPL *
; * *
; **********************************************************************
NO_IPL PROC
MOV AL,CMOS_DIAG ;GET THE
OUT CMOS_ADP,AL ; STATUS OF
JMP $+2 ; THE CMOS
IN AL,CMOS_RW ; RAM
MOV AH,AL ;SAVE IT IN AH
OR AH,HD_IPL ;DONT ALLOW
MOV AL,CMOS_DIAG ; IPL'S
OUT CMOS_ADP,AL ; FROM
JMP $+2 ; THE
MOV AL,AH ; HARD
OUT CMOS_RW,AL ; DISK
RET ;RETURN
NO_IPL ENDP
; **********************************************************************
; * *
; * WAIT FOR DRIVE TO COME READY *
; * *
; **********************************************************************
TD_READY PROC
MOV SI,TIMER_LOW ;STARTING TIME VALUE
MOV DI,SI ;ADD READY
ADD DI,READY_DELAY ; DELAY
TD_READY_00:
MOV AX,1001H ;TEST READY COMMAND
MOV CX,0001H ;CYL 0 SEC 1
INT 13H ;EXECUTE IT
JNC TD_READY_20 ;THE DRIVE IS READY
CALL TIME_CHECK ;TIMED OUT??
JNC TD_READY_00 ;NO
MOV HD_STATUS,NRDY_ER ;DRIVE NOT READY
TD_READY_10:
STC ;DRIVED TIMED OUT
RET ;RETURN
TD_READY_20:
CLC ;DRIVE READY
RET ;RETURN
TD_READY ENDP
; **********************************************************************
; * *
; * WRITE THE DRIVE PARMS AND RESET THE DRIVE *
; * *
; **********************************************************************
RS_DRIVE PROC
XOR AX,AX ;CLEAR AX
MOV AH,00H ;RESET DISK COMMAND
MOV CX,0001H ;CYL 0 SEC 1
INT 13H ;WRITE DRIVE PARMS
JC RS_DRIVE_EXIT ;FAILED
MOV AX,8101H ;SET COMPATABILITY COMMAND
INT 13H ;EXECUTE IT
JC RS_DRIVE_EXIT ;FAILED
CLC ;DRIVE READY
RS_DRIVE_EXIT:
RET ;RETURN
RS_DRIVE ENDP
; **********************************************************************
; * *
; * POST THE HARD DISK INTERRUPT *
; * *
; **********************************************************************
HD_INT PROC
PUSH DS ;SAVE DS
PUSH AX ;SAVE AX
CALL SETUP_DS ;ESTABLISH SEGMENT
ASSUME DS:DATA
MOV HD_INT_FLAG,0FFH ;INTERRUPT OCCURED
MOV AL,20H ;SEND EOI
OUT CTLR1_PORT,AL ; TO INTERRUPT CHIP 1
JMP $+2 ; AND
OUT CTLR2_PORT,AL ; TO INTERRUPT CHIP 2
STI ;ENABLE INTERRUPTS
MOV AX,9100H ;POST DEVICE
INT 15H ; INTERRUPT
POP AX ;RESTORE AX
POP DS ;RESTORE DS
IRET
HD_INT ENDP
; **********************************************************************
; * *
; * MAIN ENTRY POINT FOR INTERRUPT 13H *
; * *
; **********************************************************************
HD_IO PROC FAR
STI ;ENABLE INTERRUPTS
CMP DL,80H ;HARD DISK REQUEST??
JAE HDIO_05 ;YES
INT 40H ;MUST BE FLOPPY REQUEST
RET 2 ;AND RETURN
HDIO_05:
OR AH,AH ;RESET COMMAND??
JNZ HDIO_15 ;NO
PUSH AX ;SAVE AX
INT 40H ;RESET FLOPPIES FIRST
POP AX ;RESTORE AX
HDIO_15:
PUSH DS ;SAVE DS
PUSH ES ;SAVE ES
PUSH SI ;SAVE SI
PUSH DI ;SAVE DI
PUSH BX ;SAVE BX
PUSH CX ;SAVE CX
PUSH DX ;SAVE DX
; **********************************************************************
; * VALIDATE PARAMETERS AND COMMAND *
; **********************************************************************
ASSUME DS:DATA
CALL SETUP_DS ;ESTABLISH DATA SEGMENT
CMP AH,01H ;READ LAST STATUS??
JNE HDIO_16 ;NO
MOV AL,HD_STATUS ;SET LAST COMMAND STATUS

HDIO_16:
CMP AH,15H ;READ DASD TYPE??
JNE HDIO_17 ;NO
JMP READ_DASD ;EXECUTE IT
HDIO_17:
PUSH AX ;SAVE AX
MOV HD_STATUS,0 ;RESET ERROR CODE
AND DL,7FH ;REAL DRIVE NUMBER
CMP DL,HD_NUM ;OUT OF RANGE??
JB HDIO_18 ;NO
JMP BAD_CMD ;OUT OF RANGE
HDIO_18:
PUSH AX ;SAVE AX
CLI ;DISABLE INTERRUPTS
IN AL,CTLR1_MASK ;ENABLE
AND AL,0FFH-IRQ_2 ; INTERRUPT
OUT CTLR1_MASK,AL ; CTLR2
IN AL,CTLR2_MASK ;ENABLE THE
AND AL,0FFH-IRQ_14 ; HARD DISK
OUT CTLR2_MASK,AL ; INTERRUPT
STI ;ENABLE INTERRUPTS
POP AX ;RESTORE AX
CALL BUILD_CMD ;BUILD THE COMMAND BLOCK
; ****************************************************
TRACE 'EN'
; ****************************************************
TEST AH,80H ;SPECIAL REQUEST??
JNZ HDIO_20 ;YES
; **********************************************************************
; * PROCESS IBM COMMAND *
; **********************************************************************
MOV AL,AH ;COMPUTE
XOR AH,AH ; COMMAND TABLE
CMP AX,IBM_CMD_LIMIT ;BAD COMMAND??
JAE BAD_CMD ;YES
SHL AL,1 ; INDEX
MOV SI,AX ;INDEX REGISTER
POP AX ;RESTORE AX
JMP WORD PTR CS:[SI+OFFSET IBM_CMD_TABLE]
; **********************************************************************
; * PROCESS SPECIAL COMMAND *
; **********************************************************************
HDIO_20:
AND AH,7FH ;REAL COMMAND
MOV AL,AH ;COMPUTE
XOR AH,AH ; COMMAND TABLE
CMP AX,SPC_CMD_LIMIT ;BAD COMMAND??
JAE BAD_CMD ;YES
SHL AL,1 ; INDEX
MOV SI,AX ;INDEX REGISTER
POP AX ;RESTORE AX
JMP WORD PTR CS:[SI+OFFSET SPC_CMD_TABLE]
; **********************************************************************
; * BAD COMMAND *
; **********************************************************************
BAD_CMD:
POP AX ;RESTORE AX
BAD_CMD_1:
MOV HD_STATUS,CMD_ER ;SET BAD COMMAND
JMP HDIO_EXIT ;EXIT
; **********************************************************************
; * IBM COMMAND TABLE *
; **********************************************************************
IBM_CMD_TABLE LABEL WORD
DW RESET_DRIVE ;RESET DRIVE
DW HDIO_EXIT_2 ;GET LAST STATUS
DW READ_SECTOR ;READ SECTOR
DW WRITE_SECTOR ;WRITE SECTOR
DW VERIFY_SECTOR ;VERIFY TRACK FORMAT
DW FORMAT_TRACK ;FORMAT TRK
DW BAD_CMD_1 ;UNUSED
DW BAD_CMD_1 ;UNUSED
DW READ_DR_PARM ;GET DRIVE PARMS
DW WRITE_DR_PARM ;WRITE DRIVE PARMS
DW READ_LONG ;READ_LONG
DW WRITE_LONG ;WRITE LONG
DW DRIVE_SEEK ;SEEK
DW RESET_DRIVE ;ALT DRIVE RESET
DW BAD_CMD_1 ;UNUSED
DW BAD_CMD_1 ;UNUSED
DW DRIVE_READY ;TEST DRIVE READY
DW RECAL_SP_DRIVE ;RECALIBRATE
DW BAD_CMD_1 ;UNUSED
DW BAD_CMD_1 ;UNUSED
DW CTLR_DIAG ;CTLR INTARNAL DIAG
DW READ_DASD ;READ DASD TYPE
IBM_CMD_LIMIT EQU ($-IBM_CMD_TABLE)/2
; **********************************************************************
; * SPECIAL COMMAND TABLE *
; **********************************************************************
SPC_CMD_TABLE LABEL WORD
DW CTLR_RESET ;RESET THE CONTROLLER
DW SET_COMP ;SET COMPATABILITY
SPC_CMD_LIMIT EQU ($-SPC_CMD_TABLE)/2
; **********************************************************************
; * CLEANUP AND EXIT *
; **********************************************************************
HDIO_EXIT:
CMP HD_STATUS,020H ;CONTROLLER ERROR??
JNE HDIO_EXIT_1A ;NO
CALL XRESET_CTLR ;TRY TO RESET CONTROLLER
MOV HD_STATUS,20H ;RESTORE ERROR CODE
JMP HDIO_EXIT_1 ;EXIT
HDIO_EXIT_1A:
CMP HD_STATUS,080H ;TIMEOUT ERROR??
JNE HDIO_EXIT_1 ;NO
CALL XRESET_CTLR ;TRY TO RESET CONTROLLER
MOV HD_STATUS,80H ;RESTORE ERROR CODE
HDIO_EXIT_1:
CALL RS_DRIVE_SELECT ;RESET DRIVE 1 SELECT
CALL SETUP_DS ;ESTABLISH SEGMENT
MOV DX,HD_P6 ;PORT ADDRESS
IN AL,DX ;FETCH REGISTER
AND AL,0FFH-10H ;TURN OFF DRIVE SELECT FOR DRIVE 1
OUT DX,AL ;WRITE THE REGISTER
HDIO_EXIT_2:
MOV AH,HD_STATUS ;PUT STATUS IN AX
CMP AH,1 ;SET
CMC ; CARRY
; ****************************************************
TRACE 'XX'
; ****************************************************
POP DX ;RESTORE DX
POP CX ;RESTORE CX
POP BX ;RESTORE BX
POP DI ;RESTORE DI
POP SI ;RESTORE SI
POP ES ;RESTORE ES
POP DS ;RESTORE DS
RET 2 ;RETURN TO CALLER
; **********************************************************************
; * *
; * RETURN DASD TYPE *
; * *
; **********************************************************************
READ_DASD:
POP AX ;CLEAN UP
POP AX ; THE STACK
AND DL,7FH ;DRIVE NUMBER
CMP DL,HD_NUM ;IN RANGE??
JB READ_D00 ;YES
XOR AX,AX ;NO DRIVE
XOR CX,CX ;NO
XOR DX,DX ; SECTORS
JMP READ_DASD_EXIT ;AND EXIT
READ_D00:
MOV HD_DRIVE,DL ;SAVE DRIVE NUMBER
CALL GET_PARM_ADR ;FETCH TABLE ENTRY
XOR AX,AX ;CLEAR AX
XOR BX,BX ;CLEAR BX
MOV BL,ES:[DI+14] ;SECTORS PER TRACK
MOV AL,ES:[DI+2] ;MAX HEADS
IMUL BL ;SECTORS PER TRACK
MOV BX,ES:[DI] ;MAX CYLINDERS
DEC BX ;DIAG CYLINDER
IMUL BX ;TOTAL SECTORS
MOV CX,DX ;SETUP
MOV DX,AX ; FOR
XOR AX,AX ; RETURN
MOV AH,03H ;HARD DISK
READ_DASD_EXIT:
MOV HD_STATUS,0 ;NO ERRORS
CLC ;COMMAND SUCESSFULL
POP BX ;RESTORE BX
POP DI ;RESTORE DI
POP SI ;RESTORE SI
POP ES ;RESTORE ES
POP DS ;RESTORE DS
RET 2 ;RETURN TO CALLER
; **********************************************************************
; * TEST FOR DRIVE READY *
; **********************************************************************
DRIVE_READY:
CALL CTLR_READY ;CONTROLLER AVAILABLE??
JNC DRIVE_READY_00 ;YES
JMP HDIO_EXIT ;NO
DRIVE_READY_00:
MOV AL,HD_DRIVE ;ALIGN
MOV CX,4 ; DRIVE SELECT
SHL AL,CL ; AND SELECT
MOV DX,HD_P6 ;PORT ADDRESS
OR AL,HD_REQ ;REQUIED I GUESS
OUT DX,AL ; THE DRIVE
CALL GET_STATUS ;GET DRIVE STATUS
JMP HDIO_EXIT ;AND EXIT
; **********************************************************************
; * RESET DRIVE *
; **********************************************************************
RESET_DRIVE:
CALL XRESET_CTLR ;RESET ALL DISKS
JMP HDIO_EXIT ;ERROR
; **********************************************************************
; * RECALIBRATE DRIVE *
; **********************************************************************
RECAL_SP_DRIVE:
CALL RECAL_DRIVE ;RECALIBRATE THE DRIVE
JMP HDIO_EXIT ;ERROR
; **********************************************************************
; * READ SECTOR *
; **********************************************************************
READ_SECTOR:
MOV HD_CMD,READ_CMD ;DISK COMMAND
CALL EXEC_CMD ;EXECUTE THE COMMAND
JMP HDIO_EXIT ;AND EXIT
; **********************************************************************
; * READ LONG *
; **********************************************************************
READ_LONG:
MOV HD_CMD,READ_LONG_CMD ;DISK COMMAND
CALL EXEC_CMD ;EXECUTE THE COMMAND
JMP HDIO_EXIT ;AND EXIT
; **********************************************************************
; * WRITE SECTOR *
; **********************************************************************
WRITE_SECTOR:
MOV HD_CMD,WRITE_CMD ;DISK COMMAND
CALL EXEC_CMD ;EXECUTE THE COMMAND
JMP HDIO_EXIT ;AND EXIT
; **********************************************************************
; * WRITE LONG *
; **********************************************************************
WRITE_LONG:
MOV HD_CMD,WRITE_LONG_CMD ;DISK COMMAND
CALL EXEC_CMD ;EXECUTE THE COMMAND
JMP HDIO_EXIT ;AND EXIT
; **********************************************************************
; * VERIFY SECTOR *
; **********************************************************************
VERIFY_SECTOR:
MOV HD_CMD,READ_VERIFY_CMD ;DISK COMMAND
CALL EXEC_CMD ;EXECUTE THE COMMAND
JMP HDIO_EXIT ;AND EXIT
; **********************************************************************
; * FORMAT TRACK *
; **********************************************************************
FORMAT_TRACK:
PUSH ES ;SAVE ES
PUSH BX ;SAVE BX
CALL GET_PARM_ADR ;FETCH DRIVE TABLE ADDRESS
MOV AL,ES:[DI+14] ;SECTORS PER TRACK
MOV HD_SCNT,AL ;SET SECTOR COUNT
POP BX ;RESTORE BX
POP ES ;RESTORE ES
MOV HD_CMD,FORMAT_TRK_CMD ;DISK COMMAND
CALL EXEC_CMD ;EXECUTE THE COMMAND
JMP HDIO_EXIT ;AND EXIT
; **********************************************************************
; * WRITE DRIVE PARMS (IBM COMMAND) *
; **********************************************************************
WRITE_DR_PARM:
CALL SET_DPARMS ;WRITE THE DRIVE PARM FOR DRIVE X
JMP HDIO_EXIT ;AND EXIT
; **********************************************************************
; * SEEK *
; **********************************************************************
DRIVE_SEEK:
MOV HD_CMD,SEEK_CMD ;DISK COMMAND
CALL EXEC_CMD ;EXECUTE THE COMMAND
JNC DRIVE_SEEK_EXIT ;SUCESSFULL
CMP HD_STATUS,SEEK_ER ;SEEK ERROR??
JNE DRIVE_SEEK_EXIT ;NO - SOMETHING ELSE
CALL WAIT_SEEK ;GIVE IT SOME TIME
DRIVE_SEEK_EXIT:
JMP HDIO_EXIT ;FAILED
; **********************************************************************
; * CTLR DIAGNOSTIC *
; **********************************************************************
CTLR_DIAG:
MOV HD_CMD,CTLR_DIAG_CMD ;DISK COMMAND
CALL EXEC_CMD ;EXECUTE THE COMMAND
CTLR_DIAG_EXIT_1:
JMP HDIO_EXIT ;AND EXIT
; **********************************************************************
; * READ DRIVE PARAMETERS *
; **********************************************************************
READ_DR_PARM:
CALL GET_PARM_ADR ;GET TABLE ENTRY IN ES:DI
MOV DH,ES:[DI] ;CYL LOW
MOV DL,ES:[DI+1] ;CYL HIGH
MOV CL,6 ;ALIGN
SHL DL,CL ; CYL LOW
SUB DH,2 ;0 TO N & DIAG CYLINDER
MOV CX,DX
OR CL,ES:[DI+14] ;SECTORS PER TRACK
MOV DH,ES:[DI+2] ;MAX HEADS
DEC DH ;0 TO N
MOV DL,HD_NUM ;WORKING DRIVES
MOV HD_STATUS,0 ;ZERO RETURN CODE
;
POP AX ;RESTORE DX
POP AX ;RESTORE CX
POP BX ;RESTORE BX
POP DI ;RESTORE DI
POP SI ;RESTORE SI
POP ES ;RESTORE ES
POP DS ;RESTORE DS
CLC ;NO ERRORS
RET 2 ;RETURN TO CALLER
;
; SPECIAL COMMANDS
;
; **********************************************************************
; * RESET AT CONTROLLER *
; **********************************************************************
CTLR_RESET:
; ****************************************************
TRACE 'R8'
; ****************************************************
MOV AL,HD_RESET ;RESET CONTROLLER CMD
MOV CX,1000 ;WAIT COUNT
MOV DX,HD_REG ;PORT ADDRESS
OUT DX,AL ;ISSUE RESET COMMAND
SPCRES_00:
DEC CX ;GIVE THE CONTROLLER
JNZ SPCRES_00 ; SOME TIME
XOR AL,AL ;TURN OFF
MOV DX,HD_REG ;PORT ADDRESS
OUT DX,AL ; RESET
CALL CTLR_READY ;CONTROLLER READY??
JMP HDIO_EXIT ;AND EXIT
; **********************************************************************
; * SET DRIVE COMPATABILITY *
; **********************************************************************
SET_COMP:
CALL GET_PARM_ADR ;GET DRIVE ENTRY
MOV AL,ES:[DI+14] ;MAX SECTORS
DEC AL ;TRY THIS SECTOR FIRST
MOV HD_SCNT,01H ;SECTOR COUNT
MOV HD_CYLLO,00H ;CYL LOW
MOV HD_CYLHI,00H ;CYL HIGH
MOV HD_HEAD,00H ;HEAD
MOV HD_SNUM,AL ;SECTOR NUMBER
MOV HD_CMD,READ_VERIFY_CMD ;READ VERIFY COMMAND
CALL EXEC_CMD ;EXECUTE IT
JC SET_COMP_20 ;FAILED - SET DRIVE IN AT MODE
INC HD_SNUM ;TRY THE LAST SECTOR
CALL EXEC_CMD ;EXECUTE IT
JNC SET_COMP_20 ;SET DRIVE IN AT MODE
SET_COMP_10:
MOV AL,HD_PC ;PC COMPATABILITY MODE
JMP SET_COMP_30 ;CONTINUE
SET_COMP_20:
MOV AL,HD_AT ;AT MODE
SET_COMP_30:
CMP HD_DRIVE,01H ;DRIVE 1??
JE SET_COMP_35 ;YES
AND HD_COMP,0FH ;RESET COMPATABILITY
MOV CL,4 ;ALIGN
SHL AL,CL ; FOR DRIVE 0
OR HD_COMP,AL ;SET MODE
JMP SET_COMP_40 ;CONTINUE
SET_COMP_35:
AND HD_COMP,0F0H ;RESET COMPATABILITY
OR HD_COMP,AL ;SET MODE
SET_COMP_40:
CALL RS_DRIVE_SELECT ;RESET DRIVE 1 SELECT
MOV HD_STATUS,0 ;IGNORE ANY ERRORS
CLC ;SUCESSFULL
POP DX ;RESTORE DX
POP CX ;RESTORE CX
POP BX ;RESTORE BX
POP DI ;RESTORE DI
POP SI ;RESTORE SI
POP ES ;RESTORE ES
POP DS ;RESTORE DS
RET 2 ;RETURN TO CALLER
HD_IO ENDP
; **********************************************************************
; * RESET DRIVE 1 SELECT *
; **********************************************************************
RS_DRIVE_SELECT PROC
CALL SETUP_DS ;ESTABLISH SEGMENT
MOV DX,HD_P6 ;PORT ADDRESS
IN AL,DX ;FETCH REGISTER
AND AL,0FFH-10H ;TURN OFF DRIVE SELECT FOR DRIVE 1
OUT DX,AL ;WRITE THE REGISTER
RET ;RETURN
RS_DRIVE_SELECT ENDP
; **********************************************************************
; * RESET THE DISK CONTROLLER *
; **********************************************************************
XRESET_CTLR PROC
; ****************************************************
TRACE 'RS'
; ****************************************************
MOV AL,HD_RESET ;RESET CONTROLLER CMD
MOV CX,1000 ;WAIT COUNT
MOV DX,HD_REG ;PORT ADDRESS
OUT DX,AL ;ISSUE RESET COMMAND
XRESET_00:
DEC CX ;GIVE THE CONTROLLER
JNZ XRESET_00 ; SOME TIME
XOR AL,AL ;TURN OFF
MOV DX,HD_REG ;PORT ADDRESS
OUT DX,AL ; RESET
CALL CTLR_READY ;CONTROLLER READY??
JC XRESET_EXIT_ER ;NO - FAILED
XRESET_10:
MOV HD_DRIVE,00H ;DRIVE 0
CALL SET_DPARMS ;SET DRIVE PARMS
JC XRESET_EXIT_1 ;FAILED
CMP HD_NUM,01H ;ONLY ONE DRIVE??
JE XRESET_EXIT ;YES - EXIT
MOV HD_DRIVE,01H ;DRIVE 1
CALL SET_DPARMS ;SET DRIVE PARMS
JC XRESET_EXIT_1 ;FAILED
XRESET_EXIT:
CLC ;SUCESSFULL - I HOPE
XRESET_EXIT_1:
RET ;AND RETURN
XRESET_EXIT_ER:
MOV HD_STATUS,CTLR_ER ;CONTROLLER ERROR
STC ;INDICATE ERROR
JMP XRESET_EXIT_1 ;AND EXIT
XRESET_CTLR ENDP
; **********************************************************************
; * SET THE DRIVE PARMS *
; **********************************************************************
SET_DPARMS PROC
CALL GET_PARM_ADR ;LOAD DRIVE PARMS ADDRESS ES:DI
MOV AL,ES:[DI+14] ;SET SECTORS
MOV HD_SCNT,AL ; PER TRACK
MOV AL,ES:[DI] ;SET CYLINDER
MOV HD_CYLLO,AL ; LOW
MOV AL,ES:[DI+1] ;SET CYLINDER
MOV HD_CYLHI,AL ; HIGH
MOV AL,ES:[DI+2] ;SET
DEC AL ; MAX
MOV HD_HEAD,AL ; HEADS
MOV HD_SNUM,01H ;SECTOR NUMBER TO 1
MOV HD_CMD,WR_PARM_CMD ;WRITE DRIVE PARMS COMMAND
CALL EXEC_CMD ;EXECUTE IT
JNC RECAL_DRIVE ;SET THE STEP RATE
; ****************************************************
TRACE 'WF'
; ****************************************************
RET ;SET PARMS FAILED
SET_DPARMS ENDP
; **********************************************************************
; * RECALIBRATE THE DRIVE *
; **********************************************************************
RECAL_DRIVE PROC
MOV HD_SCNT,01H ;SECTOR COUNT
MOV HD_CYLLO,00H ;CYL LOW
MOV HD_CYLHI,00H ;CYL HIGH
MOV HD_HEAD,00H ;HEAD
MOV HD_SNUM,01H ;SECTOR NUMBER TO 1
MOV HD_CMD,RECAL_CMD ;RECALIBRATE COMMAND
CALL EXEC_CMD ;EXECUTE IT
RET ;AND EXIT
RECAL_DRIVE ENDP
; **********************************************************************
; * *
; * THIS ROUTINE EXECUTES THE COMMAND *
; * *
; * INPUTS: HD_DCB - COMMAND BLOCK *
; * *
; * ES:BX - BUFFER ADDRESS *
; * *
; * OUTPUTS: HD_STATUS - UPDATED *
; * *
; * CY = 0 SUCESSFULL *
; * CY = 1 UNSUCESSFULL *
; * *
; * *
; **********************************************************************
EXEC_CMD PROC
; ****************************************************
TRACE 'EX'
; ****************************************************
PUSH ES ;SAVE BUFFER
PUSH BX ; ADDRESS
CALL GET_PARM_ADR ;GET DRIVE TABLE ENTRY
CALL CTLR_READY ;CONTROLLER BUSY??
JNC EXEC_CMD_15 ;NO
POP BX ;RESTORE
POP ES ; BUFFER ADDRESS
JMP EXEC_CMD_EXIT_1 ;CONTROLLER BUSY
EXEC_CMD_15:
MOV AL,ES:[DI+8] ;FETCH CONTROL BYTE
AND AL,HD_EXHD ;ALL BUT EXTRA HEAD OPTION
MOV DX,HD_REG ;PORT ADDRESS
OUT DX,AL ;SET EXTRA HEAD OPTION
MOV AX,ES:[DI+5] ;WRITE PRECOMP CYL
CMP AL,0FFH ;WRITE PRECOMP DISABELED??
JE EXEC_CMD_10 ;YES
SHR AX,1 ;DIVIDE BY 4
EXEC_CMD_10:
MOV DX,HD_P1 ;PORT ADDRESS
OUT DX,AL ;SET WRITE PRECOMP CYL
INC DX ;NEXT PORT ADDRESS
MOV AL,HD_SCNT ;SET SECTOR
OUT DX,AL ; COUNT
INC DX ;NEXT PORT ADDRESS
EXEC_CMD_20:
CMP HD_COMP,HD_AT ;EVERYTHING IN AT MODE??
JE EXEC_CMD_40 ;YES
MOV CL,0F0H ;DRIVE 0 MASK
CMP HD_DRIVE,00H ;DRIVE 0??
JE EXEC_CMD_30 ;YES
MOV CL,0FH ;DRIVE 1 MASK
EXEC_CMD_30:
MOV CH,HD_COMP ;FETCH COMPATIBILITY BYTE
AND CH,CL ;ONLY ONE DRIVE
OR CH,CH ;AT MODE??
JZ EXEC_CMD_40 ;YES
DEC HD_SNUM ;PC COMPATIBILITY
EXEC_CMD_40:
MOV AL,HD_SNUM ;SET STARTING
OUT DX,AL ; SECTOR NUMBER
INC DX ;NEXT PORT ADDRESS
MOV AL,HD_CYLLO ;SET CYLINDER
OUT DX,AL ; LOW
INC DX ;NEXT PORT ADDRESS
MOV AL,HD_CYLHI ;SET CYLINDER
OUT DX,AL ; HIGH
INC DX ;NEXT PORT ADDRESS
MOV AL,HD_DRIVE ;GET DRIVE NUMBER
MOV CL,4 ;ALIGN
SHL AL,CL ; IT
OR AL,HD_HEAD ;ADD HEAD NUMBER
OR AL,HD_REQ ;REQUIED I GUESS
OUT DX,AL ;SELECT DRIVE AND HEAD
CMP HD_CMD,WR_PARM_CMD ;SET DIRVE PARMS COMMAND??
JNE EXEC_CMD_45 ;NO
JMP EXEC_CMD_600 ;YES
EXEC_CMD_45:
TEST HD_CMD,80H ;DIAG CMD??
JNZ EXEC_CMD_100 ;YES
CMP HD_CMD,RECAL_CMD ;RECAL CMD??
JE EXEC_CMD_200 ;YES
CMP HD_CMD,SEEK_CMD ;SEEK CMD??
JE EXEC_CMD_200 ;YES
TEST HD_CMD,20H ;READ/WRITE COMMAND??
JNZ EXEC_CMD_300 ;YES
TEST HD_CMD,10H ;FORMAT TRACK COMMAND??
JNZ EXEC_CMD_500 ;YES
JMP EXEC_CMD_400 ;READ VERIFY COMMAND
; **********************************************************************
; * DIAG COMMAND *
; **********************************************************************
EXEC_CMD_100:
MOV AL,HD_CMD ;COMMAND AND MODIFIERS
JMP EXEC_CMD_800 ;CONTINUE
; **********************************************************************
; * RECAL/SEEK COMMAND *
; **********************************************************************
EXEC_CMD_200:
MOV AL,HD_CMD ;COMMAND AND MODIFIERS
OR AL,ES:[DI+9] ;ADD IN STEP RATE
JMP EXEC_CMD_800 ;CONTINUE
; **********************************************************************
; * READ/WRITE COMMAND *
; **********************************************************************
EXEC_CMD_300:
MOV AL,HD_CMD ;COMMAND AND MODIFIERS
TEST BYTE PTR ES:[DI+8],0C0H ;DISABLE RETRIRES??
JZ EXEC_CMD_310 ;NO
OR AL,01H ;NO RETRY
EXEC_CMD_310:
POP BX ;RESTORE
POP ES ; BUFFER ADDRESS
CALL BOUND_CHK ;CHECK FOR BUFFER OVERLAP
JC EXEC_CMD_EXIT_1 ;E R R O R
MOV HD_INT_FLAG,00H ;CLEAR INTERRUPT FLAG
MOV DX,HD_P7 ;PORT ADDRESS
OUT DX,AL ;ISSUE THE COMMAND
TEST HD_CMD,10H ;WRITE COMMAND??
JZ EXEC_CMD_320 ;NO - READ COMMAND
CALL WRITE_DATA ;WRITE SOME DATA
JMP EXEC_CMD_EXIT_1 ;CONTINUE
EXEC_CMD_320:
CALL READ_DATA ;READ SOME DATA
JMP EXEC_CMD_EXIT_1 ;CONTINUE
; **********************************************************************
; * READ VERIFY COMMAND *
; **********************************************************************
EXEC_CMD_400:
MOV AL,HD_CMD ;COMMAND AND MODIFIERS
TEST BYTE PTR ES:[DI+8],0C0H ;DISABLE RETRIRES??
JZ EXEC_CMD_800 ;NO
OR AL,01H ;NO RETRY
JMP EXEC_CMD_800 ;CONTINUE
; **********************************************************************
; * FORMAT TRACK COMMAND *
; **********************************************************************
EXEC_CMD_500:
POP BX ;RESTORE
POP ES ; BUFFER ADDRESS
MOV HD_INT_FLAG,00H ;CLEAR INTERRUPT FLAG
MOV AL,HD_CMD ;COMMAND AND MODIFIERS
MOV DX,HD_P7 ;PORT ADDRESS
OUT DX,AL ;ISSUE THE COMMAND
CALL WRITE_DATA ;WRITE SOME DATA
JMP EXEC_CMD_EXIT_1 ;AND EXIT

; **********************************************************************
; * SET DRIVE PARMS *
; **********************************************************************
EXEC_CMD_600:
MOV AL,HD_CMD ;COMMAND AND MODIFIERS
POP BX ;RESTORE BX
POP ES ;RESTORE ES
MOV DX,HD_P7 ;PORT ADDRESS
OUT DX,AL ;ISSUE THE COMMAND
MOV CX,3 ;RETRY COUNT
EXEC_CMD_610:
CALL CTLR_READY ;CONTROLLER BUSY??
JNC EXEC_CMD_620 ;NO
; ****************************************************
TRACE 'RL'
; ****************************************************
LOOP EXEC_CMD_610 ;TRY IT AGAIN
EXEC_CMD_620:
CALL GET_STATUS ;GET THE COMMAND STATUS
JMP EXEC_CMD_EXIT_1 ;EXIT
; **********************************************************************
; * ISSUE THE COMMAND *
; **********************************************************************
EXEC_CMD_800:
POP BX ;RESTORE BX
POP ES ;RESTORE ES
MOV HD_INT_FLAG,00H ;CLEAR INTERRUPT FLAG
MOV DX,HD_P7 ;PORT ADDRESS
OUT DX,AL ;ISSUE THE COMMAND
CALL WAIT_IRQ ;WAIT FOR THE INTERRUPT
JC EXEC_CMD_EXIT_1 ;FAILED
CALL GET_STATUS ;GET THE COMMAND STATUS
JMP EXEC_CMD_EXIT_1 ;EXIT
EXEC_CMD_EXIT:
POP BX ;RESTORE BX
POP ES ;RESTORE ES
EXEC_CMD_EXIT_1:
RET ;RETURN TO CALLER
EXEC_CMD ENDP
; **********************************************************************
; * *
; * THIS ROUTINE TRANSFERS DATA FROM THE CONTROLLER TO MEMORY *
; * *
; * ES:BX - BUFFER ADDRESS *
; * *
; **********************************************************************
READ_DATA PROC
; ****************************************************
TRACE 'RD'
; ****************************************************
MOV DI,BX ;BUFFER OFFSET
CLD ;FORWARD DIRECTION
READ_DATA_10:
CALL WAIT_IRQ ;ALLOW TIME FOR THE HARD DISK
JC READ_DATA_EXIT ;FAILED
MOV CX,256 ;NUMBER OF WORDS TO READ
MOV DX,HD_P0 ;DATA PORT
REP INSW ;READ THE DATA
TEST HD_CMD,02H ;READ ECC??
JZ READ_DATA_30 ;NO
CALL WAIT_DRQ ;ALLOW TIME FOR THE CONTROLLER
JC READ_DATA_EXIT ;FAILED
MOV DX,HD_P0 ;DATA PORT
MOV CX,4 ;NUMBER OF ECC BYTES
READ_DATA_20:
IN AL,DX ;READ A BYTE
MOV BYTE PTR ES:[DI],AL ;AND SAVE IT
INC DI ;NEXT OUTPUT BYTE
DEC CX ;ONE LESS
JNZ READ_DATA_20 ;LOOP
READ_DATA_30:
CALL GET_STATUS ;GET COMMAND STATUS
JC READ_DATA_EXIT ;ERROR
TEST HD_STAT,S_BUSY ;MORE DATA??
JNZ READ_DATA_10 ;YES - PROCESS IT
READ_DATA_EXIT:
RET ;RETURN TO CALLER
READ_DATA ENDP
; **********************************************************************
; * *
; * THIS ROUTINE TRANSFERS DATA FROM MEMORY TO THE CONTROLLER *
; * *
; * ES:BX - BUFFER ADDRESS *
; * *
; **********************************************************************
WRITE_DATA PROC
; ****************************************************
TRACE 'WR'
; ****************************************************
MOV SI,BX ;BUFFER OFFSET
CLD ;FORWARD DIRECTION
WRITE_DATA_10:
CALL WAIT_DRQ ;WAIT FOR THE TO ARRIVE
JC WRITE_DATA_EXIT ;FAILED
WRITE_DATA_15:
PUSH DS ;SAVE DS
PUSH ES ;ESTABLISH
POP DS ; SEGMENT
MOV CX,256 ;NUMBER OF WORDS TO READ
MOV DX,HD_P0 ;DATA PORT
REP OUTSW ;WRITE THE DATA
POP DS ;RESTORE DS
TEST HD_CMD,02H ;WRITE ECC??
JZ WRITE_DATA_30 ;NO
CALL WAIT_DRQ ;WAIT FOR DATA REQUEST
JC WRITE_DATA_EXIT ;FAILED
MOV CX,4 ;NUMBER OF ECC BYTES
MOV DX,HD_P0 ;DATA PORT
WRITE_DATA_20:
MOV AL,BYTE PTR ES:[SI] ;FETCH A BYTE
OUT DX,AL ;WRITE A BYTE
INC SI ;NEXT BYTE
DEC CX ;ONE LESS
JNZ WRITE_DATA_20 ;LOOP
WRITE_DATA_30:
CALL WAIT_IRQ ;WAIT FOR THE INTERRUPT
JC WRITE_DATA_EXIT ;FAILED
CALL GET_STATUS ;GET COMMAND STATUS
JC WRITE_DATA_EXIT ;ERRORS
TEST HD_STAT,S_DRQ ;MORE DATA??
JNZ WRITE_DATA_15 ;YES
WRITE_DATA_EXIT:
RET ;RETURN TO CALLER
WRITE_DATA ENDP
; **********************************************************************
; * *
; * THIS ROUTINE CHECKS FOR DATA TRANSFERS CROSSING 64K BOUNDRIES *
; * *
; * ES:BX - BUFFER ADDRESS *
; * *
; **********************************************************************
BOUND_CHK PROC
PUSH AX ;SAVE AX
OR BX,BX ;ZERO PAGE ALIGNMENT??
JZ BOUND_CHK_EXIT ;YES - OK
MOV AX,BX ;COMPUTE
XOR DX,DX ;CLEAR DX
MOV CX,16 ; PAGE
DIV CX ; ALIGNMENT
CMP HD_SCNT,80H ;MORE THEN 128 SECTORS??
JA BOUND_CHK_ERR ;YES - ERROR
BOUND_CHK_10:
MOV BX,DX ;NEW OFFSET
MOV DX,ES ;COMPUTE
ADD DX,AX ; NEW
MOV ES,DX ; SEGMENT
JMP BOUND_CHK_EXIT ;AND EXIT
BOUND_CHK_ERR:
MOV HD_STATUS,DMA_ER ;CROSSES PAGE BOUNDRY
BOUND_CHK_EXIT:
POP AX ;RESTORE AX
CMP HD_STATUS,1 ;SET
CMC ; CARRY
RET ;RETURN TO CALLER
BOUND_CHK ENDP
; **********************************************************************
; * *
; * BUILD THE COMMAND CONTROL BLOCK *
; * *
; * INPUTS: AL - NUMBER OF SECTORS/INTERLEAVE VALUE *
; * CH - CYLINDER NUMBER (LOW) *
; * CL - SECTOR NUMBER AND CYL NUM (HIGH) *
; * CCSSSSSS *
; * CC - CYLINDER *
; * SS - SECTOR *
; * DH - HEAD NUMBER *
; * DL - DRIVE NUMBER *
; * *
; * OUTPUTS: - HD_DCB COMPLETE *
; * *
; **********************************************************************
BUILD_CMD PROC
PUSH ES ;SAVE SI
PUSH BX ;SAVE BX
AND DL,7FH ;DRIVE NUMBER
MOV HD_DRIVE,DL ;AND SAVE IT
MOV HD_HEAD,DH ;HEAD NUMBER
MOV HD_SCNT,AL ;SECTOR COUNT
MOV HD_CMD,AH ;SAVE COMMAND
MOV DX,CX ;SAVE CX
MOV HD_CYLLO,CH ;CYLINDER LOW
AND DL,0C0H ;REMOVE SECTOR NUMBER
PUSH CX ;SAVE CX
MOV CL,6 ;SHIFT COUNT
SHR DL,CL ;ALIGN CYL HIGH
POP CX ;RESTORE CX
MOV HD_CYLHI,DL ;AND SAVE IT
AND CL,3FH ;ISOLATE SECTOR NUMBER
MOV HD_SNUM,CL ;AND SAVE IT
POP BX ;RESTORE BX
POP ES ;RESTORE ES
CLC ;CLEAR CARRY
RET ;RETURN TO CALLER
BUILD_CMD ENDP
; **********************************************************************
; * *
; * TEST CONTROLLER READY ROUTINE *
; * CY = 0 CONTROLLER READY *
; * CY = 1 CONTROLLER ERROR *
; **********************************************************************
CTLR_READY PROC
; **********************************************************************
TRACE 'CR'
; **********************************************************************
PUSH SI ;SAVE SI
PUSH DI ;SAVE DI
MOV SI,TIMER_LOW ;STARTING TIME
MOV DI,SI ;SETUP
ADD DI,CTLR_DELAY ; ENDING TIME
CTLR_READY_00:
MOV DX,HD_P7 ;PORT ADDRESS
IN AL,DX ;READ STATUS REGISTER
TEST AL,S_BUSY ;CONTROLLER BUSY??
JZ CTLR_READY_20 ;NO - WERE READY FOR ACTION
CALL TIME_CHECK ;CHECK FOR TIME OUT
JNC CTLR_READY_00 ;STILL SOME TIME LEFT
CTLR_READY_10:
MOV HD_STATUS,TIME_ER ;INDICATE TIME OUT
CTLR_READY_20:
POP DI ;RESTORE DI
POP SI ;RESTORE SI
CMP HD_STATUS,1 ;SET
CMC ; CARRY
RET ;AND RETURN
CTLR_READY ENDP
; **********************************************************************
; * *
; * GET COMMAND STATUS *
; * CY = 0 COMMAND SUCESSFULL *
; * CY = 1 COMMAND FAILED *
; **********************************************************************
GET_STATUS PROC
; **********************************************************************
TRACE 'ST'
; **********************************************************************
XOR AH,AH ;CLEAR AH
MOV DX,HD_P7 ;PORT ADDRESS
IN AL,DX ;READ THE STATUS REGISTER
MOV HD_STAT,AL ;SAVE STATUS REGISTER
TEST AL,S_BUSY ;CONTROLLER BUSY??
JNZ GET_STATUS_30 ;YES - NOTHING ELSE VALID
CMP HD_CMD,CTLR_DIAG_CMD ;CTLR DIAG CMD??
JE GET_STATUS_28 ;YES - SKIP THIS STUFF
GET_STATUS_20:
MOV AH,NRDY_ER ;DRIVE NOT READY
TEST AL,S_DRDY ;DRIVE READY??
JZ GET_STATUS_30 ;NO
MOV AH,WRFLT_ER ;WRITE FAULT
TEST AL,S_WRFLT ;WRITE FAULT??
JNZ GET_STATUS_30 ;YES
MOV AH,SEEK_ER ;SEEK COMPLETE
;***************************************************************************
; TEST AL,S_SEKCMP ;SEEK COMPLETE??
; JZ GET_STATUS_30 ;NO - ERROR
TEST AL,S_SEKCMP ;SEEK COMPLETE??
JNZ GET_STATUS_25 ;YES
CALL WAIT_SEEK ;GIVE IT SOME TIME
JNC GET_STATUS_25 ;SUCESSFULL
JMP GET_STATUS_30 ;FAILED
GET_STATUS_25:
;***************************************************************************
MOV AH,DATA_ER ;ECC CORRECTED DATA
TEST AL,S_CORECC ;ECC CORRECTED DATA??
JNZ GET_STATUS_30 ;YES
GET_STATUS_28:
MOV AH,0 ;NO ERRORS
TEST AL,S_ERROR ;ERROR SET??
JZ GET_STATUS_30 ;NO
CALL GET_ERROR ;FETCH THE ERROR CODE
JMP GET_STATUS_EXIT ;CONTINUE
GET_STATUS_30:
MOV HD_STATUS,AH ;SET RETURN CODE
GET_STATUS_EXIT:
CMP HD_STATUS,1 ;SET
CMC ; CARRY
RET ;AND RETURN
GET_STATUS ENDP
; **********************************************************************
; * *
; * GET ERROR CODE *
; * *
; **********************************************************************
GET_ERROR PROC
MOV DX,HD_P1 ;PORT ADDRESS
IN AL,DX ;READ THE ERROR REGISTER
MOV HD_ERR,AL ;SAVE ERROR REGISTER
CMP HD_CMD,CTLR_DIAG_CMD ;DIAG COMMAND??
JE GET_ERROR_30 ;YES
MOV CX,8 ;8 BITS TO CHECK
LEA BX,ERR_TBL ;ERROR TABLE
GET_ERROR_10:
TEST AL,01H ;ERROR BIT??
JNZ GET_ERROR_20 ;YES
INC BX ;NEXT ERROR CODE
SHR AL,1 ;SHIFT ERROR REGISTER
LOOP GET_ERROR_10 ;PROCESS THIS BIT
MOV HD_STATUS,NO_ER ;NO ERROR INDICATED
JMP GET_ERROR_EXIT ;AND EXIT
GET_ERROR_20:
XOR AH,AH ;CLEAR AH
MOV AL,CS:[BX] ;FETCH ERROR CODE
MOV HD_STATUS,AL ;SET RETURN CODE
JMP GET_ERROR_EXIT ;AND EXIT
GET_ERROR_30:
LEA BX,ERR1_TBL ;ERROR TABLE
XOR AH,AH ;CLEAR AH
ADD BX,AX ;POINT TO ERROR CODE
MOV AL,CS:[BX] ;FETCH ERROR CODE
MOV HD_STATUS,AL ;SET RETURN CODE
GET_ERROR_EXIT:
CMP HD_STATUS,1 ;SET
CMC ; CARRY
RET ;RETURN
ERR_TBL DB ADMRK_ER,SEEK_ER,CMD_ER,UNDEF_ER,NRF_ER,UNDEF_ER
DB ECC_ER,BSEC_ER
ERR1_TBL DB NO_ER,NO_ER,CTLR_ER,CTLR_ER,ECC_ER,CTLR_ER
GET_ERROR ENDP
; **********************************************************************
; * *
; * CHECK FOR TIME OUT *
; * CY = 0 TIME STILL LEFT *
; * CY = 1 TIME EXPIRED *
; * SI = STARTING TIME *
; * DI = ENDING TIME *
; * *
; **********************************************************************
TIME_CHECK PROC
MOV AX,TIMER_LOW ;GET CURRENT TIMER VALUE
CMP DI,SI ;END < START??
JB TIME_CHECK_10 ;YES
CMP AX,DI ;TIMED OUT??
JBE TIME_CHECK_30 ;NO - STILL TIME
JMP TIME_CHECK_20 ;TIMED OUT
TIME_CHECK_10:
CMP AX,SI ;>= START TIME??
JB TIME_CHECK_15 ;NO - MUST HAVE WRAPPED
JMP TIME_CHECK_30 ;STILL TIME LEFT
TIME_CHECK_15:
CMP AX,DI ;TIMED OUT??
JBE TIME_CHECK_30 ;NO - STILL TIME
JMP TIME_CHECK_20 ;TIMED OUT
TIME_CHECK_20:
IF DOSTEST
INT 03H ;CALL THE DEBUGGER
ENDIF
STC ;DRIVED TIMED OUT
; ****************************************************
TRACE 'TO'
; ****************************************************
RET ;RETURN
TIME_CHECK_30:
CLC ;DRIVE READY
RET ;RETURN
TIME_CHECK ENDP
; **********************************************************************
; * *
; * GET THE HARD DISK PARAMETER TABLE ADDRESS *
; * *
; * INPUTS: HD_DRIVE *
; * *
; * OUTPUTS: ES:DI IS THE DRIVE TABLE ADDRESS *
; * *
; **********************************************************************
GET_PARM_ADR PROC
XOR AX,AX ;ESTABLISH
MOV ES,AX ; EXTRA SEGMENT
ASSUME ES:DUMMY ;
CMP HD_DRIVE,00H ;DRIVE 0??
JNE GET_PARM_20 ;NO - DRIVE 1
LES DI,INT_41H ;LOAD THE DRIVE PARAMETERS
JMP GET_PARM_EXIT ;AND EXIT
GET_PARM_20:
LES DI,INT_46H ;LOAD THE DRIVE PARAMETERS
GET_PARM_EXIT:
RET ;AND RETURN
GET_PARM_ADR ENDP
; **********************************************************************
; * SETUP THE DS REGISTER *
; **********************************************************************
SETUP_DS PROC
PUSH AX ;SAVE AX
PUSHF ;SAVE FLAGS
MOV AX,DATA ;SEGMENT ADDRESS FOR DATA
MOV DS,AX ;ESTABLISH DATA SEGMENT
POPF ;RESTORE FLAGS
POP AX ;RESTORE AX
RET ;RETURN TO CALLER
SETUP_DS ENDP
; **********************************************************************
; * *
; * WAIT FOR INTERRUPT REQUEST *
; * CY = 0 IRQ POSTED *
; * CY = 1 ERROR OCCURED *
; **********************************************************************
WAIT_IRQ PROC
; **********************************************************************
TRACE 'IR'
; **********************************************************************
PUSH SI ;SAVE SI
PUSH DI ;SAVE DI
MOV SI,TIMER_LOW ;STARTING TIME
MOV DI,SI ;SETUP
ADD DI,IRQ_DELAY ; ENDING TIME
WAIT_IRQ_00:
TEST HD_INT_FLAG,80H ;INTERRUPT POSTED??
JNZ WAIT_IRQ_EXIT ;YES
MOV DX,HD_P7 ;PORT ADDRESS
IN AL,DX ;READ STATUS REGISTER
TEST AL,S_BUSY ;CONTROLLER BUSY??
JNZ WAIT_IRQ_10 ;YES - STILL WORKING
TEST HD_INT_FLAG,80H ;INTERRUPT POSTED??
JNZ WAIT_IRQ_EXIT ;YES
CALL GET_STATUS ;GET THE ERROR STATUS
JMP WAIT_IRQ_EXIT ;AND EXIT
WAIT_IRQ_10:
CALL TIME_CHECK ;TIMED OUT??
JNC WAIT_IRQ_00 ;NO - KEEP ON TRUCKING
MOV HD_STATUS,TIME_ER ;TIME OUT ERROR
WAIT_IRQ_EXIT:
MOV HD_INT_FLAG,00H ;CLEAR INTERRUPT FLAG
CMP HD_STATUS,1 ;SET
CMC ; CARRY
POP DI ;RESTORE DI
POP SI ;RESTORE SI
RET ;AND RETURN
WAIT_IRQ ENDP
; **********************************************************************
; * *
; * WAIT FOR SEEK COMPLETE *
; * CY = 0 IRQ POSTED *
; * CY = 1 ERROR OCCURED *
; **********************************************************************
WAIT_SEEK PROC
; **********************************************************************
TRACE 'WS'
; **********************************************************************
PUSH SI ;SAVE SI
PUSH DI ;SAVE DI
MOV HD_STATUS,00H ;CLEAR ERRORS
MOV SI,TIMER_LOW ;STARTING TIME
MOV DI,SI ;SETUP
ADD DI,SEEK_DELAY ; ENDING TIME
WAIT_SEEK_00:
MOV DX,HD_P7 ;PORT ADDRESS
IN AL,DX ;READ STATUS PORT
TEST AL,S_SEKCMP ;SEEK COMPLETE??
JNZ WAIT_SEEK_EXIT ;YES
TEST AL,S_ERROR ;ERROR SET??
JNZ WAIT_SEEK_EXIT ;YES
CALL TIME_CHECK ;TIMED OUT??
JNC WAIT_SEEK_00 ;NO - KEEP ON TRUCKING
MOV AH,SEEK_ER ;SEEK ERROR
MOV HD_STATUS,AH ;SET ERROR
WAIT_SEEK_EXIT:
CMP HD_STATUS,1 ;SET
CMC ; CARRY
POP DI ;RESTORE DI
POP SI ;RESTORE SI
RET ;AND RETURN
WAIT_SEEK ENDP
; **********************************************************************
; * *
; * WAIT FOR DATA REQUEST *
; * CY = 0 DRQ PRESENT *
; * CY = 1 DRQ TIMED OUT *
; * *
; **********************************************************************
WAIT_DRQ PROC
; **********************************************************************
TRACE 'DQ'
; **********************************************************************
PUSH SI ;SAVE SI
PUSH DI ;SAVE DI
MOV SI,TIMER_LOW ;STARTING TIME
MOV DI,SI ;SETUP
ADD DI,DRQ_DELAY ; ENDING TIME
WAIT_DRQ_00:
MOV DX,HD_P7 ;PORT ADDRESS
IN AL,DX ;READ STATUS REGISTER
TEST AL,S_DRQ ;DATA REQUEST??
JNZ WAIT_DRQ_EXIT ;YES
CALL TIME_CHECK ;TIME EXPIRED??
JNC WAIT_DRQ ;NO - CONTINUE
MOV HD_STATUS,TIME_ER ;INDICATE TIME OUT
WAIT_DRQ_EXIT:
CMP HD_STATUS,1 ;SET
CMC ; CARRY
POP DI ;RESTORE DI
POP SI ;RESTORE SI
RET ;RETURN
WAIT_DRQ ENDP
; **********************************************************************
; * *
; * TRACE ROUTINE *
; * AL = TYPE *
; * *
; **********************************************************************
TRACE_IT PROC
PUSHF ;SAVE FLAGS
PUSH DS ;SAVE DS
PUSH DX ;SAVE DX
PUSH AX ;SAVE AX
PUSHF ;MOV FLAGS
POP DX ; TO DX
XOR AX,AX ;ESTABLISH
MOV DS,AX ; SEGMENT
POP AX ;RESTORE AX
ASSUME DS:DUMMY
CMP WORD PTR INT_64H,55AAH ;TRACE ROUTINE PRESENT ??
JNE TRACE_EXIT ;NO
INT 67H ;TRACE THIS ENTRY
TRACE_EXIT:
POP DX ;RESTORE DX
POP DS ;RESTORE DS
POPF ;RESTORE FLAGS
RET ;RETURN
TRACE_IT ENDP
CODE ENDS
ENDER