;* NOTE: FIXDSK.ASM modified 12/22/85 by C. Washburn to use INT 40H instead of
;  13H, and to restore contents of AH when retrying. INT 40H change was based
;  the notion that NOTHING should get in the Fixed Disk INT 13H code path if
;  at all possible! INT 40H is the relocated address of the BIOS Diskette code,
;  after the Fixed Disk Controller ROM installs itself, and is only and exclu-
;  sively for Floppy I/O.

;===================================================================
;FIXDSK.ASM - corrects floppy disk timeout problem on speeded-up AT.
;
;-------------------------------------------------------------------
;MODIFIED 12/22/85 by C. Washburn, to use INT 40 instead of INT 13
;(the relocated diskette code when a fixed disk is present), and to
;restore the entry code in AH when retrying.
;
;Indicated Modifications are (C)Copyright 1985 Clyde Washburn,
;and are placed in the Public Domain.
;-------------------------------------------------------------------
;Create FIXDSK.COM as follows:
;
;	 MASM FIXDSK.ASM;
;	 LINK FIXDSK;
;	 EXE2BIN FIXDSK.EXE FIXDSK.COM
;
;Then place FIXDSK.COM in your AUTOEXEC.BAT file.
;
;  (C)Copyright 1985 Michael J. Markowitz
;		     Department of Mathematical Sciences
;		     Loyola University of Chicago
;		     Chicago, IL  60626
;		     (312) 508-3567
;
;This program may be freely copied and used for noncommercial purposes.
;Under no circumstances may a fee be charged for its distribution nor
;may it be included in any commercial hardware or software package
;without the written consent of the owner.
;==================================================================
TIME_OUT equ	 80h

vectors segment at 0h
	 org	 40h * 4		 ;CW - 40h was 13h
int_40h  label	 dword			 ;CW - ditto
int_40h_ip	 dw	 ?		 ;CW - ditto
int_40h_cs	 dw	 ?		 ;CW - ditto
vectors ends

code	 segment
	 assume  cs:code
	 org	 100h
start:	 jmp	 init

ah_cont		 db	 ?		 ;CW - save AH entry contents here
old_int_40h label dword			 ;CW - 40h was 13h
old_int_ip	 dw	 ?
old_int_cs	 dw	 ?

ret_addr label	 dword
ret_addr_ip	 dw	 ?
ret_addr_cs	 dw	 ?

flags		 dw	 ?

main	 proc	 far
	 mov	 cs:ah_cont,ah		 ;CW - save AH for possible reuse
	 pushf				 ;simulate original disk interrupt
	 call	 old_int_40h		 ;CW - 40h was 13h
	 pushf				 ;   and save returned flags
	 pop	 flags
	 jnc	 fin			 ;if no error, return to caller

	 cmp	 ah,TIME_OUT		 ;is it a timeout error?
	 jne	 fin			 ;   if no, return to caller

	 pushf				 ;   if yes, try one more time
	 mov	 ah,cs:ah_cont		 ;CW - restore AH for retry
	 call	 old_int_40h		 ;CW - 40h was 13h

fin:	 pop	 ret_addr_ip		 ;simulate an INTR
	 pop	 ret_addr_cs
	 add	 sp,2
	 push	 flags			 ;return flags from first ROM
	 popf				 ;   BIOS call
	 jmp	 ret_addr
main	 endp

init	 proc
	 assume  ds:vectors		 ;establish addressability of
	 mov	 ax,vectors		 ;   interrupt vectors
	 mov	 ds,ax

	 mov	 ax,int_40h_ip		 ;save old disk interrupt vector
	 mov	 old_int_ip,ax		 ;(line above) CW - 40h was 13h
	 mov	 ax,int_40h_cs		 ;CW - 40h was 13h
	 mov	 old_int_cs,ax

	 mov	 int_40h_ip,offset main  ;replace with dword ;CW - 40h was 13h
	 mov	 int_40h_cs,cs		 ;  pointer to fixdsk ;CW - ditto

	 mov	 dx,offset init
	 int	 27h			 ;terminate leaving main resident
init	 endp

db	 'INT 40H VERSION OF 12/22/85'	 ;CW - internal Modification ID

code	 ends
	 end	 start
