Tvůrce webu je i pro tebe! Postav třeba web. Bez grafika. Bez kodéra. Hned.
wz

DOS_DSK.ASM

Obsluha disků


; ============================================================================
;
;                            MicroDOS - DOS disk
;
; ============================================================================

MAXFAT		EQU	12		; max FAT sectors, FAT12, 4096 clusters

; ------------- DOS Drive Parameter Block, DDPB

struc		DDPB

DDPB_disk:	resb	1		; 0: logical drive number (0=A:)
DDPB_sector:	resw	1		; 1: bytes per sector
DDPB_maxsect:	resb	1		; 3: highest sector number in cluster
DDPB_shifts:	resb	1		; 4: shift count to convert clusters
					;    into sectors
DDPB_boot:	resw	1		; 5: starting sector of first FAT
DDPB_fat:	resb	1		; 7: number of FATs
DDPB_root:	resw	1		; 8: number of directory entries
DDPB_databeg:	resw	1		; 0Ah: number of first data sector
DDPB_maxclust:	resw	1		; 0Ch: highest cluster number
					;      (= number of data clusters + 1)
DDPB_fatsec:	resb	1		; 0Eh: sectors per FAT
DDPB_rootbeg:	resw	1		; 0Fh: starting sector of directory
DDPB_modi:	resb	1		; 11h: flag, 1=FAT buffer is modified
DDPB_buf:	resb	MAXFAT*SECTORSIZE ; 12h: FAT buffer

endstruc

DDPB_SIZE	EQU	DDPB_size	; 12h+MAXFAT*SECTORSIZE = 6162 bytes

; ------------- FAT12 cluster types

FAT12_FREE	EQU	0		; free cluster
FAT12_MAX	EQU	0fefh		; maximum data cluster
FAT12_RES	EQU	0ff0h		; reserved (up to 0ff6h)
FAT12_BAD	EQU	0ff7h		; bad cluster
FAT12_END	EQU	0ff8h		; end of cluster chain (up to 0fffh)

; ----------------------------------------------------------------------------
;                             Read from disk
; ----------------------------------------------------------------------------
; INPUT:	CX = number of sectors to read
;		DX = starting sector number
;		SS:BP = disk DDPB
;		DS:BX = data buffer
; OUTPUT:	CY = error
;		AH = status (see "BIOS disk error codes")
;		AL = DOS error code (see "Device driver error codes")
;		CX = number of remaining sectors (0 if NC)
;		DI = required number of sectors to read
; ----------------------------------------------------------------------------

ReadDisk:	mov	al,[bp+DDPB_disk] ; AL <- drive number
		mov	di,cx		; DI <- number of sectors
		push	cs		; simulate call far
		call	JVTReadDisk	; read from disk
		ret

; ----------------------------------------------------------------------------
;                               Write to disk
; ----------------------------------------------------------------------------
; INPUT:	CX = number of sectors to write
;		DX = starting sector number
;		SS:BP = disk DDPB
;		DS:BX = data buffer
; OUTPUT:	CY = error
;		AH = status (see "BIOS disk error codes")
;		AL = DOS error code (see "Device driver error codes")
;		CX = number of remaining sectors (0 if NC)
;		DI = required number of sectors to write
; ----------------------------------------------------------------------------

WriteDisk:	mov	al,[bp+DDPB_disk] ; AL <- drive number
		mov	di,cx		; DI <- number of sectors
		push	cs		; simulate call far
		call	JVTWriteDisk	; write to disk
		ret

; ----------------------------------------------------------------------------
;                        Read from disk with error handling
; ----------------------------------------------------------------------------
; INPUT:	CX = number of sectors to read
;		DX = starting sector number
;		SS:BP = disk DDPB
;		DS:BX = data buffer
; ----------------------------------------------------------------------------

; ------------- Push registers

ReadDiskErr:	push	ax		; push AX
		push	di		; push DI

; ------------- Read from disk

ReadDiskErr2:	push	cx		; push CX
		call	ReadDisk	; read from disk
		pop	cx		; pop CX
		jnc	ReadDiskErr4	; operation OK

; ------------- Error service

		mov	byte [cs:ErrorType],0 ; set error type - read
		call	DoDiskInt24	; do Int 24h disk error routine
		cmp	al,1		; repeat operation?
		je	ReadDiskErr2	; repeat operation

; ------------- Pop registers

ReadDiskErr4:	pop	di		; pop DI
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                        Write to disk with error handling
; ----------------------------------------------------------------------------
; INPUT:	CX = number of sectors to write
;		DX = starting sector number
;		SS:BP = disk DDPB
;		DS:BX = data buffer
; ----------------------------------------------------------------------------

; ------------- Push registers

WriteDiskErr:	push	ax		; push AX
		push	di		; push DI

; ------------- Write to disk

WriteDiskErr2:	push	cx		; push CX
		call	WriteDisk	; write to disk
		pop	cx		; pop CX
		jnc	WriteDiskErr4	; operation OK

; ------------- Error service

		mov	byte [cs:ErrorType],1 ; set error type - write
		call	DoDiskInt24	; do Int 24h disk error routine
		cmp	al,1		; repeat operation?
		je	WriteDiskErr2	; repeat operation

; ------------- Pop registers

WriteDiskErr4:	pop	di		; pop DI
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                   Get next cluster from FAT table
; ----------------------------------------------------------------------------
; INPUT:	BX = current cluster number
;		SS:BP = disk DDPB
;		DS = data segment
; OUTPUT:	DI = next cluster number
; ----------------------------------------------------------------------------

; ------------- Push registers

GetCluster:	push	ax		; push AX
		push	bx		; push BX

; ------------- Check cluster number

		cmp	bx,[bp+DDPB_maxclust] ; check cluster number
		jbe	GetCluster2	; cluster number is OK

; ------------- Critical error

		mov	ah,B7		; AH <- error flag, bad FAT image
		mov	di,0fffh	; DI <- error code, bad FAT image
		call	DoInt24		; execute Int 24h error handler
		jmp	short GetCluster8

; ------------- Address in FAT buffer

GetCluster2:	lea	di,[bp+DDPB_buf] ; DI <- buffer
		add	di,bx		; DI <- offset
		shr	bx,1		; cluster / 2, CY = odd cluster
		mov	di,[bx+di]	; DI <- cluster

; ------------- Prepare cluster number

		jnc	GetCluster4	; it is even cluster
		shr	di,1
		shr	di,1
		shr	di,1
		shr	di,1		; shift cluster number
GetCluster4:	and	di,0fffh	; mask cluster number

; ------------- Pop registers

GetCluster8:	pop	bx		; pop BX
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                     Set next cluster to FAT table
; ----------------------------------------------------------------------------
; INPUT:	BX = current cluster number
;		SS:BP = disk DDPB
;		DS = data segment
; 		DX = next cluster number
; ----------------------------------------------------------------------------

; ------------- Push registers

SetCluster:	push	ax		; push AX
		push	bx		; push BX
		push	di		; push DI

; ------------- Prepare address in buffer

		lea	di,[bp+DDPB_buf] ; DI <- buffer
		add	di,bx		; DI <- offset
		shr	bx,1		; cluster / 2, CY = odd cluster
		lea	bx,[bx+di]	; BX <- address

; ------------- Load number of cluster

		mov	ax,[bx]		; AX <- cluster
		jnc	SetCluster2	; it is even cluster

		shl	dx,1
		shl	dx,1
		shl	dx,1
		shl	dx,1		; shift cluster number
		and	ax,byte 0fh	; mask old cluster number
		jmp	short SetCluster4

SetCluster2:	and	ax,0f000h	; mask old cluster number

; ------------- Set new cluster number

SetCluster4:	or	ax,dx		; add new cluster number
		mov	[bx],ax		; set new cluster number

; ------------- Set FAT buffer modified flag

		mov	byte [bp+DDPB_modi],1 ; set FAT buffer modified flag

; ------------- Pop registers

		pop	di		; pop DI
		pop	bx		; pop BX
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                   Prepare registers for FAT read/write
; ----------------------------------------------------------------------------
; INPUT:	SS:BP = disk DDPB
; OUTPUT:	AX = number of FATs
;		BX = FAT buffer
;		CX = sectors per FAT
;		DX = starting sector number
; ----------------------------------------------------------------------------

PrepareFAT:	mov	al,[bp+DDPB_fat] ; AL <- number of FATs
		cbw			; AX <- number of FATs
		lea	bx,[bp+DDPB_buf] ; BX <- FAT buffer
		xor	cx,cx		; CX <- 0
		mov	cl,[bp+DDPB_fatsec] ; CX <- sectors per FAT
		mov	dx,[bp+DDPB_boot] ; DX <- starting sector number
		ret

; ----------------------------------------------------------------------------
;                           Read FAT table from disk
; ----------------------------------------------------------------------------
; INPUT:	SS:BP = disk DDPB
;		DS = data segment
; ----------------------------------------------------------------------------

; ------------- Push registers

ReadFAT:	call	PushABCDI	; push registers AX, BX, CX, DX, DI

; ------------- Check if FAT sector in buffer is modified

		cmp	byte [bp+DDPB_modi],0 ; FAT buffer is modified?
		jne	ReadFAT8	; FAT buffer is modified

; ------------- Check if disk buffer contains modified data

		mov	al,[bp+DDPB_disk] ; AL <- disk
		mov	ah,1		; AH <- 1 modified flag
		cmp	ax,[DataDiskModi] ; is data buffer modified?
		je	ReadFAT8	; data buffer is modified

; ------------- Reset data buffer parameters

		cmp	al,[DataDisk]	; check current disk of buffer
		jne	ReadFAT3	; it is not current disk
		mov	word [DataSector],0 ; reset sector of data buffer
		mov	word [DataDiskModi],0ffh ; disk invalid, no modify

; ------------- Reset Root entry index

ReadFAT3:	mov	word [RootSectDisk],-1 ; sector+disk in Root buffer

; ------------- Read FAT sectors

		call	PrepareFAT	; prepare FAT parameters
ReadFAT4:	push	ax		; push AX
		call	ReadDisk	; read from disk
		pop	ax		; pop AX
		jnc	ReadFAT8	; read OK

; ------------- Read next FAT copy

		mov	cx,di		; CX <- original number of sectors
		add	dx,di		; DX <- sector of next FAT copy
		dec	ax		; counter of FATs
		jnz	ReadFAT4	; next FAT copy

; ------------- On error - finally one more attempt with error handling

		call	PrepareFAT	; prepare FAT parameters
		call	ReadDiskErr	; read from disk with error handling

; ------------- Pop registers

ReadFAT8:	call	PopABCDI	; pop registers AX, BX, CX, DX, DI
		ret

; ----------------------------------------------------------------------------
;                          Write FAT table to disk
; ----------------------------------------------------------------------------
; INPUT:	SS:BP = disk DDPB
;		DS = data segment
; ----------------------------------------------------------------------------

; ------------- Check if FAT buffer is modified

WriteFAT:	cmp	byte [bp+DDPB_modi],0 ; FAT buffer is modified?
                je	WriteFAT8	; FAT buffer is not modified
		mov	byte [bp+DDPB_modi],0 ; clear FAT buffer modified flag

; ------------- Push registers

		call	PushABCDI	; push registers AX, BX, CX, DX, DI

; ------------- Prepare FAT parameters

		call	PrepareFAT	; prepare FAT parameters

; ------------- Write FAT table

WriteFAT2:	push	ax		; push AX
		call	WriteDiskErr	; write to disk with error handling
		pop	ax		; pop AX

; ------------- Next FAT table

		add	dx,cx		; sector of next FAT
		dec	ax		; counter of FAT tables
		jnz	WriteFAT2	; write next FAT table

; ------------- Pop registers

		call	PopABCDI	; pop registers AX, BX, CX, DX, DI
WriteFAT8:	ret

; ----------------------------------------------------------------------------
;                   Prepare registers for ROOT read/write
; ----------------------------------------------------------------------------
; INPUT:	AL = relative number of sector
;		SS:BP = disk DDPB
; OUTPUT:	BX = FAT buffer
;		CX = sectors per FAT
;		DX = starting sector number
; ----------------------------------------------------------------------------

PrepareRoot:	push	ax		; push AX
		cbw			; AX <- AL
		add	ax,[bp+DDPB_rootbeg] ; AX <- starting sector number
		xchg	ax,dx		; DX <- startin sector number
		mov	bx,RootBuf	; BX <- Root buffer
		mov	cx,1		; CX <- 1 number of sectors
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                       Set Root modified flag
; ----------------------------------------------------------------------------

SetRootModi:	mov	byte [cs:RootModi],0ffh ; buffer is modified
		ret

; ----------------------------------------------------------------------------
;                 Set modify flag and write Root sector to disk
; ----------------------------------------------------------------------------
; INPUT:	DS = data segment
;		SS:BP = DDPB of the disk
; ----------------------------------------------------------------------------

ModiWriteRoot:	call	SetRootModi	; set Root modification flag

; WriteRoot must follow!

; ----------------------------------------------------------------------------
;                        Write Root sector to disk
; ----------------------------------------------------------------------------
; INPUT:	DS = data segment
;		SS:BP = DDPB of the disk
; ----------------------------------------------------------------------------

; ------------- Push registers

WriteRoot:	call	PushABCDI	; push registers AX, BX, CX, DX, DI

; ------------- Check if Root buffer is modified

		cmp	byte [RootModi],0 ; is Root buffer modified?
		je	WriteRoot8	; Root buffer is not modified
		mov	byte [RootModi],0 ; flag, buffer is not modified

; ------------- Prepare parameters for operation

		mov	al,[RootSect]	; AL <- current Root sector
		call	PrepareRoot	; prepare parameters

; ------------- Write sector to disk

		call	WriteDiskErr	; write to disk with error handling

; ------------- Pop registers

WriteRoot8:	call	PopABCDI	; pop registers AX, BX, CX, DX, DI
		ret

; ----------------------------------------------------------------------------
;                          Read Root sector from disk
; ----------------------------------------------------------------------------
; INPUT:	AL = Root sector index
;		DS = data segment
;		SS:BP = DDPB of the disk
; ----------------------------------------------------------------------------

; ------------- Write Root sector to disk

ReadRoot:	call	WriteRoot	; write Rot sector to disk

; ------------- Push registers

		call	PushABCDI	; push registers AX, BX, CX, DX, DI

; ------------- Store new current sector and disk

		mov	ah,[bp+DDPB_disk] ; AH <- disk
		mov	[RootSectDisk],ax ; store sector and disk

; ------------- Read Root sector from disk

		call	PrepareRoot	; prepare parameters
		call	ReadDiskErr	; read sector from disk

; ------------- Pop registers
                                          
		call	PopABCDI	; pop registers AX, BX, CX, DX, DI
		ret

; ----------------------------------------------------------------------------
;                            Get next Root entry
; ----------------------------------------------------------------------------
; INPUT:	DS = data segment
;		SS:BP = DDPB of the disk
; OUTPUT:	CY = no Root entry
;		BX = address in buffer
; ----------------------------------------------------------------------------

; ------------- Push registers

GetNextRoot:	push	ax		; push AX
		push	dx		; push DX

; ------------- Increase index of Root entry

		mov	ax,[RootIndex]	; AX <- current index of Root entry
		inc	ax		; increase index
		cmp	ax,[bp+DDPB_root] ; check index of Root entry
		jb	GetNextRoot2	; index of Root entry is OK

; ------------- Write Root sectors

		call	WriteRoot	; write Root to disk
		stc			; set error flag
		jmp	short GetNextRoot8

GetNextRoot2:	mov	[RootIndex],ax	; store new index of Root entry

; ------------- Prepare number of Root sector and offset in sector

		mov	dx,DIR_SIZE	; DX <- size of one directory entry
		mul	dx		; DX:AX <- offset in Root
		mov	bx,[bp+DDPB_sector] ; BX <- size of sector
		div	bx		; AL <- sector, DX <- offset in sector
		push	dx		; push DX, offset in sector

; ------------- Check if this sector is already in Root buffer

		mov	ah,[bp+DDPB_disk] ; AH <- disk
		cmp	ax,[RootSectDisk] ; is this sector already in buffer?
		je	GetNextRoot4	; sector is already in Root buffer

; ------------- Read Root sector into buffer

		call	ReadRoot	; read Root sector from disk

; ------------- Offset in Root buffer (clears CF)

GetNextRoot4:	pop	bx		; pop BX (offset in Root buffer)
		add	bx,RootBuf	; BX <- address in Root buffer

; ------------- Pop registers

GetNextRoot8:	pop	dx		; pop DX
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                       Store parameters for data buffer
; ----------------------------------------------------------------------------
; INPUT:	DX = starting sector number
;		SS:BP = disk DDPB
; ----------------------------------------------------------------------------

StoreDataPar:	push	ax
		mov	al,[bp+DDPB_disk] ; AL <- disk
		mov	[cs:DataDisk],al ; store disk
		mov	[cs:DataSector],dx ; sector number
		pop	ax
		ret

; ----------------------------------------------------------------------------
;                        Set data buffer modified flag
; ----------------------------------------------------------------------------

SetDataModi:	mov	byte [cs:DataModi],1 ; set data modified flag
		ret

; ----------------------------------------------------------------------------
;                          Write data buffer to disk
; ----------------------------------------------------------------------------
; INPUT:	SS:BP = disk DDPB (according to data in buffer)
; ----------------------------------------------------------------------------

; ------------- Push registers

WriteData:	push	bx		; push BX
		push	cx		; push CX
		push	dx		; push DX
		push	ds		; push DS

; ------------- Prepare data segment

		push	cs		; push CS
		pop	ds		; DS <- CS

; ------------- Check if buffer is modified

		cmp	byte [DataModi],0 ; is data buffer modified?
		je	WriteData9	; data buffer is not modified
		mov	byte [DataModi],0 ; clear modified flag

; ------------- Write data buffer to disk

		mov	bx,DataBuffer	; BX <- data buffer
		mov	cx,1		; CX <- 1 number of sectors
		mov	dx,[DataSector]	; DX <- sector number
		call	WriteDiskErr	; write sector to disk

; ------------- Pop registers

WriteData9:	pop	ds		; pop DS
		pop	dx		; pop DX
		pop	cx		; pop CX
		pop	bx		; pop BX
		ret

; ----------------------------------------------------------------------------
;                         Free cluster chain
; ----------------------------------------------------------------------------
; INPUT:	BX = first cluster number
;		SS:BP = disk DDPB
;		DS = data segment
; ----------------------------------------------------------------------------

; ------------- Push registers

FreeChain:	push	bx		; push BX
		push	dx		; push DX
		push	di		; push DI

; ------------- Get next cluster number (-> DI)

FreeChain2:	call	GetCluster	; get next cluster number
		or	di,di		; is cluster valid?
		jz	FreeChain8	; invalid cluster

; ------------- Clear cluster number

		xor	dx,dx		; DX <- 0, flag of free cluster
		call	SetCluster	; set cluster number

; ------------- Next cluster

		mov	bx,di		; BX <- next cluster
		cmp	bx,FAT12_END	; end of chain?
		jb	FreeChain2	; next cluster

; ------------- Pop registers

FreeChain8:	pop	di		; pop DI
		pop	dx		; pop DX
		pop	bx		; pop BX	
		ret

; ----------------------------------------------------------------------------
;                           Get DDPB of disk
; ----------------------------------------------------------------------------
; INPUT:	AL = disk (0=default disk, 1=A:, 2=B, ...)
; OUTPUT:	CY = invalid disk
;		SS:BP = disk DDPB
; DESTROYS:	AX
; ----------------------------------------------------------------------------

; ------------- Check drive number

GetDDPB:	cmp	al,MAXDISK+1	; check disk number
		cmc			; CY = invalid disk
		jc	GetDDPB6	; invalid disk

; ------------- Addres of disk table (and clear CF)

		cbw			; AX <- AL
		shl	ax,1		; AX <- disk number * 2
		xchg	ax,bp		; BP <- disk number
		mov	bp,[bp+DiskDDPBAddr] ; BP <- address of DDPB
GetDDPB6:	ret

; ----------------------------------------------------------------------------
;                      Execute Int 24h disk error routine
; ----------------------------------------------------------------------------
; INPUT:	DS:BX = data buffer
;		CX = number of remaining sectors
;		DX = start sector number
;		DI = required number of sectors
;		SS:BP = address of DDPB
; OUTPUT:	AL = action code (0=ignore, 1=retry, 2=terminate, 3=fail)
; DESTROYS:	AH
; ----------------------------------------------------------------------------

; ------------- Push registers

DoDiskInt24:	push	bx		; push BX
		push	dx		; push DX
		push	di		; push DI

; ------------- Accept transfered sectors

		xchg	ax,di		; AX <- required number of sectors
		sub	ax,cx		; AX <- successfully transfered sectors
		add	dx,ax		; DX <- shift start sector number
		push	dx		; push DX
		mov	dx,[bp+DDPB_sector] ; DX <- size of sector
		mul	dx		; AX <- length of sectors
		pop	dx		; pop DX
		add	bx,ax		; BX <- shift data buffer

; ------------- Disk area

		mov	ah,0		; disk area - BOOT
		cmp	dx,[bp+DDPB_boot] ; is it BOOT sector?
		jb	DoDiskInt242	; it is BOOT sector
		mov	ah,1		; disk area - FAT
		cmp	dx,[cs:FirstRoot] ; first Root sector
		jb	DoDiskInt242	; it is FAT sector
		mov	ah,2		; disk area - Root
		cmp	dx,[cs:FirstData] ; first data sector
		jb	DoDiskInt242	; it is Root sector
		mov	ah,3		; disk area - data
DoDiskInt242:	shl	ah,1		; shift disk area to bits 1-2

; ------------- Read or write operation

		add	ah,[cs:ErrorType] ; AH <- error type, read/write

; ------------- Execute Int 24h error routine

		call	DoInt24		; execute Int 24h error routine

; ------------- Pop registers

		pop	di		; pop DI
		pop	dx		; pop DX
		pop	bx		; pop BX
		ret

; ----------------------------------------------------------------------------
;                         Execute Int 24h error routine
; ----------------------------------------------------------------------------
; INPUT:	AL = drive number
;		AH = type and processing flags (see below)
;		DI = error code
;		SS:BP = address of DDPB
; OUTPUT:	AL = action code (0=ignore, 1=retry, 2=terminate, 3=fail)
; DESTROYS:	AH
; ----------------------------------------------------------------------------
; Int 24h handler:
;  INPUT:
;	AL = drive number if bit 7 of AH is clear
;	AH = type and processing flags
;		bit 7:	0=disk I-O error
;			1=bad FAT image in memory (block device)
;				or error code in DI (char device)
;		bit 5:	1=ignore allowed
;		bit 4:	1=retry allowed
;		bit 3:	1=fail allowed
;		bit 1,2: disk area of error
;				0=Boot, 1=FAT, 2=Root, 3=Data
;		bit 0:	1=Write, 0=Read
;	DI = error code if AH bit 7 is set, see Device driver error codes
;			0FFFFh = bad FAT image in memory
;	STACK:	[SP+0]: (2) offset of return address for Int 24h
;		[SP+2]: (2) segment of return address for Int 24h
;		[SP+4]: (2) flags pushed with Int 24h
;		[SP+6]: (2) AX
;		[SP+8]: (2) BX
;		[SP+10]: (2) CX
;		[SP+12]: (2) DX
;		[SP+14]: (2) SI
;		[SP+16]: (2) DI
;		[SP+18]: (2) BP
;		[SP+20]: (2) DS
;		[SP+22]: (2) ES
;		[SP+24]: (2) offset of return address for Int 21h
;		[SP+26]: (2) segment return address for Int 21h
;		[SP+28]: (2) flags pushed with Int 21h
;  OUTPUT: 
;	AL = action code (0=ignore, 1=retry, 2=terminate, 3=fail)
; ----------------------------------------------------------------------------

; ------------- Prepare drive number

DoInt24:	mov	al,[bp+DDPB_disk] ; AL <- drive number

; ------------- Push stack

		cli			; disable interrupts
		push	bp		; push BP
		mov	[cs:Int24SP],sp	; push SP register

; ------------- Restore old stack pointer

		mov	ss,[cs:OldStack+2]; return SS
		mov	sp,[cs:OldStack] ; return SP

; ------------- Call Int 24h routine

		int	24h		 ; call Int 24h routine

; ------------- Store new stack pointer

		mov	[cs:OldStack],sp ; store new SP
		mov	[cs:OldStack+2],ss ; store new SS

; ------------- Pop stack

		mov	sp,cs		; SP <- CS
		mov	ss,sp		; SS <- CS
		mov	sp,[cs:Int24SP]	; pop SP register
		pop	bp		; pop BP
		sti			; enable interrupts

; ------------- Terminate program

		cmp	al,2		; terminate program?
		jne	DoInt242	; it is not terminate program
		jmp	Terminate	; terminate program
DoInt242:	ret

; ----------------------------------------------------------------------------
;               Int 21h, function 0Dh - disk reset
; ----------------------------------------------------------------------------
; INT21 INPUT:	AH = 0Dh (function code)
; ----------------------------------------------------------------------------

; ------------- Prepare data segment

Int210D:	push	cs		; push CS
		pop	ds		; DS <- data segment

; ------------- Set current disk to A:

		mov	ax,[DiskDDPBAddrA] ; AX <- address of A: DDPB
		mov	[DiskDDPBAddr],ax ; set current disk to A:

; ------------- Disk reset, check if data buffer is modified

DiskAllReset:	mov	ax,[DataDiskModi] ; AL <- disk, AH <- modified flag
		or	ah,ah		; is data buffer modified?
		jz	Int210D4	; data buffer is not modified

; ------------- Write data buffer to disk

		cbw			; AX <- disk
		shl	ax,1		; AX *= 2
		xchg	ax,bx		; BX <- offset in DDPB table
		mov	bp,[bx+DiskDDPBAddrA] ; BP <- DDPB of disk
		call	WriteData	; write data buffer to disk

; ------------- Write Root buffer

Int210D4:	call	WriteRoot	; write Root buffer

; ------------- Write all FAT tables to disk

		mov	si,DiskDDPBAddrA ; SI <- DDPB table
		mov	cx,MAXDISK	; CX <- number of drives
Int210D6:	cld			; direction up
		lodsw			; AX <- address of next buffer
		xchg	ax,bp		; BP <- DDPB table
		call	WriteFAT	; write FAT table to disk
		loop	Int210D6	; write next DAT
		ret

; ----------------------------------------------------------------------------
;                                    Data
; ----------------------------------------------------------------------------

DTA:		dd	0		; segment and offset of DTA address

ErrorType:	db	0		; error type: 1=write, 0=read

FirstRoot:	dw	0		; first ROOT sector
FirstData:	dw	0		; first data sector

; ------------- Table of DDPB addresses (0=current disk, 1=A:, ...)

DiskDDPBAddr:	dw	DiskDDPBA	; address of current disk DDPB
DiskDDPBAddrA:	dw	DiskDDPBA	; address of A: DDPB
		dw	DiskDDPBB	; address of B: DDPB
		dw	DiskDDPBC	; address of C: DDPB
		dw	DiskDDPBD	; address of D: DDPB

; ------------- Disk data buffer

DataDiskModi:
DataDisk:	db	0ffh		; current disk of data bufferu
DataModi:	db	0		; 1=modified flag, 0=no

DataSector:	dw	0		; sector of data buffer

; ------------- data for Int 24h routine

Int24SP:	dw	0		; push SP register for Int 24h

Zpět na stránku systému MICRODOS