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

DISK.ASM

Block Device


; =============================================================================
;
;                             Litos - Block device
;
; =============================================================================

		CODE_SECTION	32

; -----------------------------------------------------------------------------
;                             Read sectors from track
; -----------------------------------------------------------------------------
; INPUT:	EAX = start sector number (1...)
;		EBX = floppy disk device parameter block FLOPPY
;		ECX = number of sectors
;		EDX = data buffer
;		ESI = head
;		EDI = cylinder
; OUTPUT:	EAX = sectors OK read
;		CY = error
; -----------------------------------------------------------------------------

DiskReadTrk:	DRVFNC	ebx,DISKF_ReadTrk

; -----------------------------------------------------------------------------
;                             Write sectors to track
; -----------------------------------------------------------------------------
; INPUT:	EAX = start sector number (1...)
;		EBX = floppy disk device parameter block FLOPPY
;		ECX = number of sectors
;		EDX = data buffer
;		ESI = head
;		EDI = cylinder
; OUTPUT:	EAX = sectors OK written
;		CY = error
; -----------------------------------------------------------------------------

DiskWriteTrk:	DRVFNC	ebx,DISKF_WriteTrk

; -----------------------------------------------------------------------------
;                         Verify sectors from track
; -----------------------------------------------------------------------------
; INPUT:	EAX = start sector number (1...)
;		EBX = floppy disk device parameter block FLOPPY
;		ECX = number of sectors
;		ESI = head
;		EDI = cylinder
; OUTPUT:	EAX = sectors OK verified
;		CY = error
; -----------------------------------------------------------------------------

DiskVerifyTrk:	DRVFNC	ebx,DISKF_VerifyTrk

; -----------------------------------------------------------------------------
;                          Compare sectors from track
; -----------------------------------------------------------------------------
; INPUT:	EAX = start sector number (1...)
;		EBX = floppy disk device parameter block FLOPPY
;		ECX = number of sectors
;		EDX = data buffer
;		ESI = head
;		EDI = cylinder
; OUTPUT:	EAX = sectors OK compared
;		CY = error
; -----------------------------------------------------------------------------

DiskCompTrk:	DRVFNC	ebx,DISKF_CompTrk

; -----------------------------------------------------------------------------
;                        Format track (without verify)
; -----------------------------------------------------------------------------
; INPUT:	AL = formatting filler byte
;		EBX = floppy disk device parameter block FLOPPY
;		ESI = head
;		EDI = cylinder
; OUTPUT:	CY = error
; -----------------------------------------------------------------------------

DiskFormatTrk:	DRVFNC	ebx,DISKF_FormatTrk

; -----------------------------------------------------------------------------
;                          Calculate media size
; -----------------------------------------------------------------------------
; INPUT:	EBX = block device DISK
; NOTES:	Input parameters are cylinders, heads and sectors per track.
; -----------------------------------------------------------------------------

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

DiskCalcMedia:	push	eax		; push EAX
		push	ecx		; push ECX
		push	edx		; push EDX
		push	esi		; push ESI

; ------------- Calculate total number of tracks (heads*cylinders -> EDX:EAX)

		mov	eax,[ebx+DISK_Heads] ; EAX <- number of heads
		mul	dword [ebx+DISK_Tracks] ; EDX:EAX <- total tracks

; ------------- Calculate total number of sectors (-> ESI:EAX)

		mov	ecx,[ebx+DISK_TrackSect] ; ECX <- sectors per track
		xchg	eax,esi		; ESI <- tracks LOW
		xchg	eax,edx		; EAX <- tracks HIGH
		mul	ecx		; EAX <- sectors HIGH
		xchg	eax,esi		; ESI <- sectors HIGH,EAX <- tracks LOW
		mul	ecx		; EDX:EAX <- sectors LOW
		add	edx,esi		; EDX <- sectors HIGH
		mov	[ebx+DISK_SectNum],eax ; store sectors LOW
		mov	[ebx+DISK_SectNum+4],edx ; store sectors HIGH

; ------------- Calculate media size in bytes

		mov	cl,[ebx+DDEV_GranBits] ; CL <- granularity bits
		shld	edx,eax,cl	; rotate EDX:EAX << CL
		shl	eax,cl		; rotate EAX << CL
		mov	[ebx+DDEV_Size],eax ; set total size LOW
		mov	[ebx+DDEV_Size+4],edx ; set total size HIGH

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

		pop	esi		; pop ESI
		pop	edx		; pop EDX
		pop	ecx		; pop ECX
		pop	eax		; pop EAX
		ret

; -----------------------------------------------------------------------------
;                       Prepare parameters for operation
; -----------------------------------------------------------------------------
; INPUT:	EDX:EAX = data offset
;		EBX = block device DISK
;		ECX = data length (bytes)
;		ESI = data buffer
; OUTPUT:	EAX = starting sector on track (1...)
;		ECX = number of sectors
;		EDX = data buffer
;		ESI = head
;		EDI = cylinder
;		CY = invalid disk parameters (TrackSect or Heads is zero)
; -----------------------------------------------------------------------------

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

DiskPrepPar:	push	esi		; push ESI (data buffer)
		push	ebp		; push EBP

; ------------- Check disk parameters

		cmp	dword [ebx+DISK_TrackSect],byte 1 ; sectors per track
		jb	DiskPrepPar8	; invalid parameter
		cmp	dword [ebx+DISK_Heads],byte 1 ; number of heads
		jb	DiskPrepPar8	; invalid parameter

; ------------- Prepare starting sector (-> ESI:EDI)

		push	ecx		; push ECX (data length)
		xchg	eax,edi		; EDI <- current position LOW
		mov	esi,edx		; ESI <- current position HIGH
		mov	cl,[ebx+DDEV_GranBits] ; CL <- granularity bits
		shrd	edi,esi,cl	; rotate position >> CL
		shr	esi,cl		; rotate position HIGH
		pop	eax		; pop EAX (data length)

; ------------- Prepare number of sectors (-> EAX)

		shr	eax,cl		; EAX <- number of sectors

; ------------- Get sector on track (-> EBP) and track (-> ESI:EDI)

		xor	edx,edx		; EDX <- 0
		xchg	eax,esi		; EAX <- sector HIGH, ESI <- sectors
		mov	ecx,[ebx+DISK_TrackSect] ; ECX <- sectors per track
		div	ecx		; EAX <- track number HIGH, EDX <- rest
		xchg	eax,esi		; ESI <- track number HIGH,EAX<-sectors
		xchg	eax,edi		; EAX <- sector number LOW,EDI<-sectors
		div	ecx		; EAX <- track number LOW,EDX <- sector
		inc	edx		; EDX <- sector + 1
		xchg	eax,edi		; EDI <- track number LOW, EAX<-sectors
		mov	ebp,edx		; EBP <- sector number (1...)

; ------------- Get head (-> ESI) and cylinder (-> EDI)

		xor	edx,edx		; EDX <- 0
		xchg	eax,esi		; EAX <- track HIGH, ESI <- sectors
		mov	ecx,[ebx+DISK_Heads] ; ECX <- number of heads
		div	ecx		; EAX <- cylinder HIGH, EDX <- rest
		xchg	eax,esi		; ESI <- cylinder HIGH, EAX <- sectors
		xchg	eax,edi		; EAX <- track LOW, EDI <- sectors
		div	ecx		; EAX <- cylinder LOW, EDX <- head
		xchg	eax,edi		; EDI <- cylinder LOW, EAX <- sectors
		xchg	eax,ecx		; ECX <- number of sectors
		xchg	eax,ebp		; EAX <- sector number (1...)
		xchg	edx,esi		; EDX <- cylinder HIGH, ESI <- head

; ------------- Limit cylinder number on overflow (it clears CF)

		or	edx,edx		; cylinder overflow?
		jz	DiskPrepPar8	; no overflow
		xor	edi,edi		; EDI <- 0
		dec	edi		; EDI <- -1, max. cylinder on overflow

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

DiskPrepPar8:	pop	ebp		; pop EBP
		pop	edx		; pop EDX (data buffer)
		ret

; -----------------------------------------------------------------------------
;                             Limit number of sectors
; -----------------------------------------------------------------------------
; INPUT:	EAX = starting sector on track (1...)
;		EBX = block device DISK
;		ECX = number of sectors
; OUTPUT:	ECX = limited number of sectors
; -----------------------------------------------------------------------------

DiskLimitSect:	push	edx		; push EDX
		mov	edx,[ebx+DISK_TrackSect] ; EDX <- sectors per track
		inc	edx		; EDX <- sectors per track + 1		
		sub	edx,eax		; EDX <- remaining sectors
		cmp	edx,ecx		; check number of sectors
		ja	DiskLimitSect4	; number of sectors is OK
		mov	ecx,edx		; ECX <- limit number of sectors
DiskLimitSect4:	pop	edx		; pop EDX
		ret

; -----------------------------------------------------------------------------
;                         Shift to next sectors
; -----------------------------------------------------------------------------
; INPUT:	EAX = sectors OK
;		EBX = block device DISK
;		ECX = number of sectors
;		EDX = data buffer
;		ESI = head
;		EDI = cylinder
; OUTPUT:	CY = continue with next track, NC = end of operation
;		EAX = 1, new first sector on track
;		ECX = new number of sectors
;		EDX = new data buffer
;		ESI = new head
;		EDI = new cylinder
; -----------------------------------------------------------------------------

; ------------- Shift remaining sectors

DiskShiftNext:	sub	ecx,eax		; shift remaining sectors
		jbe	DiskShiftNext8	; no other data required

; ------------- Shift address

		push	ecx		; push ECX
		mov	cl,[ebx+DDEV_GranBits] ; CL <- granularity bits
		shl	eax,cl		; EAX <- convert sectors to bytes
		add	edx,eax		; EDX <- shift address
		pop	ecx		; pop ECX

; ------------- Prepare new first sector on track (-> EAX)

		xor	eax,eax		; EAX <- 0
		inc	eax		; EAX <- 1, new first sector on track

; ------------- Shift head and track

		inc	esi		; increase head number
		cmp	esi,[ebx+DISK_Heads] ; check head number
		jb	DiskShiftNext6	; head number is OK
		xor	esi,esi		; ESI <- 0, head on next cylinder
		inc	edi		; increase cylinder number

; ------------- Continue

DiskShiftNext6:	stc			; flag to continue
		ret

; ------------- End of operation

DiskShiftNext8:	clc			; end of operation
		ret

; -----------------------------------------------------------------------------
;                            Get result of operation
; -----------------------------------------------------------------------------
; INPUT:	EBP = sectors OK
;		EBX = block device DISK
; OUTPUT:	EAX = bytes OK
; DESTROYS:	EBP, ECX
; NOTES:	It saves flags
; -----------------------------------------------------------------------------

DiskGetResult:	pushf			; push flags
		xchg	eax,ebp		; EAX <- number of sectors
		mov	cl,[ebx+DDEV_GranBits] ; CL <- granularity bits
		shl	eax,cl		; EAX <- convert sectors to bytes
		popf			; pop flags
		ret

; -----------------------------------------------------------------------------
;                              Read data from disk
; -----------------------------------------------------------------------------
; INPUT:	EDX:EAX = data offset
;		EBX = block device DISK
;		ECX = data length (bytes)
;		ESI = data buffer
; OUTPUT:	EAX = bytes OK read
;		CY = error
; -----------------------------------------------------------------------------

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

DiskRead:	push	ecx		; push ECX
		push	edx		; push EDX
		push	esi		; push ESI
		push	edi		; push EDI
		push	ebp		; push EBP

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

		xor	ebp,ebp		; EBP <- 0, data counter
		call	DiskPrepPar	; prepare parameters
		jc	short DiskWrite9 ; disk parameters error

; ------------- Check cylinder number

DiskRead2:	cmp	edi,[ebx+DISK_Tracks] ; check cylinder number
		jae	short DiskWrite9 ; invalid cylinder number

; ------------- Limit number of sectors (-> ECX)

		push	ecx		; push ECX
		call	DiskLimitSect	; limit number of sectors

; ------------- Read sectors from track

		call	DiskReadTrk	; read sectors from track
		pop	ecx		; pop ECX

; ------------- Shift sector counter

		pushf			; push flags
		add	ebp,eax		; add sector number
		popf			; pop flags
		jc	short DiskWrite9 ; error

; ------------- Shift to next sector

		call	DiskShiftNext	; shift to next sector
		jc	short DiskRead2	; next track
		jmp	short DiskWrite9

; -----------------------------------------------------------------------------
;                              Write data to disk
; -----------------------------------------------------------------------------
; INPUT:	EDX:EAX = data offset
;		EBX = block device DISK
;		ECX = data length (bytes)
;		ESI = data buffer
; OUTPUT:	EAX = bytes OK written
;		CY = error
; -----------------------------------------------------------------------------

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

DiskWrite:	push	ecx		; push ECX
		push	edx		; push EDX
		push	esi		; push ESI
		push	edi		; push EDI
		push	ebp		; push EBP

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

		xor	ebp,ebp		; EBP <- 0, data counter
		call	DiskPrepPar	; prepare parameters
		jc	short DiskWrite9 ; disk parameters error

; ------------- Check cylinder number

DiskWrite2:	cmp	edi,[ebx+DISK_Tracks] ; check cylinder number
		jae	short DiskWrite9 ; invalid cylinder number

; ------------- Limit number of sectors (-> ECX)

		push	ecx		; push ECX
		call	DiskLimitSect	; limit number of sectors

; ------------- Write sectors to track

		call	DiskWriteTrk	; write sectors to track
		pop	ecx		; pop ECX

; ------------- Shift sector counter

		pushf			; push flags
		add	ebp,eax		; add sector number
		popf			; pop flags
		jc	short DiskWrite9 ; error

; ------------- Shift to next sector

		call	DiskShiftNext	; shift to next sector
		jc	short DiskWrite2 ; next track

; ------------- Get mumber of bytes

DiskWrite9:	call	DiskGetResult	; get result of operation

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

		pop	ebp		; pop EBP
		pop	edi		; pop EDI
		pop	esi		; pop ESI
		pop	edx		; pop EDX
		pop	ecx		; pop ECX
		ret

; -----------------------------------------------------------------------------
;                              Verify data from disk
; -----------------------------------------------------------------------------
; INPUT:	EDX:EAX = data offset
;		EBX = block device DISK
;		ECX = data length (bytes)
; OUTPUT:	EAX = bytes OK verified
;		CY = error
; -----------------------------------------------------------------------------

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

DiskVerify:	push	ecx		; push ECX
		push	edx		; push EDX
		push	esi		; push ESI
		push	edi		; push EDI
		push	ebp		; push EBP

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

		xor	ebp,ebp		; EBP <- 0, data counter
		call	DiskPrepPar	; prepare parameters
		jc	short DiskWrite9 ; disk parameters error

; ------------- Check cylinder number

DiskVerify2:	cmp	edi,[ebx+DISK_Tracks] ; check cylinder number
		jae	short DiskWrite9 ; invalid cylinder number

; ------------- Limit number of sectors (-> ECX)

		push	ecx		; push ECX
		call	DiskLimitSect	; limit number of sectors

; ------------- Verify sectors from track

		call	DiskVerifyTrk	; verify sectors from track
		pop	ecx		; pop ECX

; ------------- Shift sector counter

		pushf			; push flags
		add	ebp,eax		; add sector number
		popf			; pop flags
		jc	short DiskWrite9 ; error

; ------------- Shift to next sector

		call	DiskShiftNext	; shift to next sector
		jc	short DiskVerify2 ; next track
		jmp	short DiskWrite9

; -----------------------------------------------------------------------------
;                            Compare data from disk
; -----------------------------------------------------------------------------
; INPUT:	EDX:EAX = data offset
;		EBX = block device DISK
;		ECX = data length (bytes)
;		ESI = data buffer
; OUTPUT:	EAX = bytes OK compared
;		CY = error
; -----------------------------------------------------------------------------

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

DiskCompare:	push	ecx		; push ECX
		push	edx		; push EDX
		push	esi		; push ESI
		push	edi		; push EDI
		push	ebp		; push EBP

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

		xor	ebp,ebp		; EBP <- 0, data counter
		call	DiskPrepPar	; prepare parameters
		jc	short DiskWrite9 ; disk parameters error

; ------------- Check cylinder number

DiskCompare2:	cmp	edi,[ebx+DISK_Tracks] ; check cylinder number
		jae	short DiskWrite9 ; invalid cylinder number

; ------------- Limit number of sectors (-> ECX)

		push	ecx		; push ECX
		call	DiskLimitSect	; limit number of sectors

; ------------- Compare sectors from track

		call	DiskCompTrk	; compare sectors from track
		pop	ecx		; pop ECX

; ------------- Shift sector counter

		pushf			; push flags
		add	ebp,eax		; add sector number
		popf			; pop flags
		jc	short DiskWrite9 ; error

; ------------- Shift to next sector

		call	DiskShiftNext	; shift to next sector
		jc	short DiskCompare2 ; next track
		jmp	short DiskWrite9

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

		DATA_SECTION

Back to source browser