Créer l' image d'une disquette [tasm]

Description

Si vous souhaitez comprendre comment lire le contenu d'une disquette en assembleur 8086 ou bien si vous souhaitez avoir un chtit programme (vraiment chtit : 1 ko) pour créer l'image d'une disquette et bien c'est là que ça se passe...
(Le programme crée floppy.img, seulement pour des disquettes de 1.44MO, l'image est créee à l'emplacement du programme)
Je rappelle qu'une disquette est constituée de 2 faces, composées chacunes de 80 pistes, supportants chacune 18 secteurs.
De plus, l'ordre de lecture est "spécial" : on lit tout d'abord la piste 0 de la face 0, on passe ensuite sur la face 1, pour lire la piste 0, on revient ensuite sur la face 0 et on s'occupe de la piste 1, puis de la piste 1 de la face 1, ect....
Cette structure de la disquette un peu étrange (pourquoi ne pas lire tout d'abord la face 0 entièrement puis la face 1....) permet aux 2 têtes de lectures de travailler plus efficacement, cad à tour de rôle...

Source / Exemple :


;CODE ASM x86 COMPILE SOUS TASM 4.1

;------------------------SEGMENT DE DONNEES-------------------------
;-------------------------------------------------------------------
_data segment public
	Buffer	DB 512 Dup(0)		;buffer correspondant à 1 secteur
	floppy  db 'FLOPPY.IMG',0
	err1 	db 'Erreur du lecteur de disquette',10,13,'$'
	err2 	db 'Erreur fichier',10,13,'$'
	Handle	dw ?			;pointeur sur fichier
_data ends
;-------------------------------------------------------------------

;------------------------SEGMENT DE CODE----------------------------
;-------------------------------------------------------------------
_code segment public
	assume cs:_code, ss:_stack

	start:

		;synchronise le segment de donnée avec ds ainsi que es
			mov	ax, _data
			mov	ds, ax
			mov	es, ax
		
		;initialise le lecteur de disquette
			xor	ah, ah		;mets la fonction 00h dans ah pour "initialiser un disque"
			xor	dl, dl		;précise le numéro du disque à réinitialiser(00h pour le disquette A:)
			int	13h		;par l'int 13 (lecteur de disquette)
			jc	erreur1		;si CF=1 alors on affiche une erreur
		
		;création du fichier floppy.img
			mov	ah, 3Ch		;fonction 3Ch pour créer un fichier ou vider un fichier s'il existe déjà
			mov	cx, 00h		;attribut du fichier : on mets 0 pour que l'on puisse -écrire-
			mov	dx, Offset floppy        ;@ du nom du fichier dans dx
			int	21h		;interruption dos
			jc	erreur2		;s'il s'est produit une erreur alors on arrête tout :)
			mov	[ds:Handle], ax	;mets dans la variable "Handle" le pointeur sur le fichier

		;copie de la disquette (chaque boucle lit un secteur de la disquette et l'écrit dans le fichier)

			;initialisation des compteurs de la boucle (entre autres)
				mov	al, 01h		;on lit un seul secteur à chaque fois
				xor	dx, dx		;#lecteur disquette 0 + #face 0
				xor	cx, cx		;#piste 0 + #secteur 0
				inc	cl		;euh en fait #secteur 1 :-)
				mov	bx, Offset Buffer;endroit ou l'on lit
				mov	ah, 01h			

			;debut de la copie			
				jmp	faire

	tantque:
			inc	cl
			cmp	cl,19		;il y a 18 secteurs par piste
			jne	faire

			mov	cl, 1
			inc	dh
			cmp	dh, 2		;il y a 2 faces par disques
			jne	faire
			
			xor	dh, dh
			inc	ch
			cmp	ch, 80		;il y a 80 pistes par face
			je	fintantque
			
	faire:		

		;lecture d'un secteur de la disquette	
			mov	ah, 02h		;ATTENTION il faut mettre 02 avant CHAQUE lecture
			int	13h		;en effet si la lecture est un succès, ah vaut alors 00h
			jc	erreur1

		;écriture de ce que l'on vient de lire
			push	ax			;on sauvegarde quelques registres
			push	bx
			push	cx
			push	dx
				mov	ah, 40h		;fonction 40h pour écrire dans un fichier
				mov	bx, [ds:Handle]	;on précise dans bx le pointeur sur le fichier
				mov	cx, 512		;nombre d'octets à écrire
				mov	dx, Offset Buffer;@ du buffer à écrire
				int	21h		;interruption dos pour écrire
				jc	erreur2		;s'il s'est produit une erreur alors on arrête tout :)
			pop	dx
			pop	cx
			pop	bx
			pop	ax

		jmp	tantque

	fintantque:

			mov	al, 00h
			jmp	fin

	erreur1:
		mov	dx, Offset err1
		jmp	erreur
	erreur2:
		mov	dx, Offset err2
		jmp	erreur
	erreur:
		mov	ah, 09h				;fonction d'affichage 09 (via le dos)
		int	21h				;interruption pour afficher err1 ou err2
		mov	al, 01h				;on mets dans al le code d'erreur 1
		jmp	fin				
	fin:
		mov	ah, 4Ch				;fonction 4Ch de sortie de programme avec code d'erreur
		int	21h				;interruption pour sortir

_code ends
;--------------------------------------------------------------------

;------------------------SEGMENT DE LA PILE--------------------------
;--------------------------------------------------------------------
_stack segment stack
	db 100h dup (?)			;déclare une pile de 256 octets
_stack ends
;--------------------------------------------------------------------

;------------------------SAUT AU DEBUT DU PROGRAMME------------------
	end start
;--------------------------------------------------------------------

Conclusion :


Rq: Je dois bien avouer que la 1ère fois j'ai lu entièrement la face 0 puis la face 1 (je ne savais pas comment on lisait une disquette il fallait bien que je choisisse une méthode :) ) et mon image était quelque peu décousue...de plus le temps de lecture s'en étais avérer être beaucoup plus long.... je me suis dit que pê il (euh le lecteur...) passait d'une tête à une autre, et c'est bien le cas....

Amélioration possible: A la moindre erreur de lecture ou d'écriture le programme se stoppe, on pourrait retenter une lecture ou écriture en cas d'échec, et si il y a 5 erreurs consécutives, alors seulement on arrêterait le programme... A vos souris...

Si vous n'avez pas tout compris au code ou si vous avez des commentaires, des améliorations à apporter (et il y en a sûrement), n'hésitez pas à poster, a+

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.