	section NIBBLE,code_C

	opt	x+


;********************************************************
; Début du programme

Start
	bsr	save_all
	bsr	Init_Drive

readalldisk:
	move.w	#0,d0
	lea	track2(pc),a0	;adresse de piste dans a0
	bsr	ReadTrack		;lecture
	tst.l	d0
	bne	error		;ça n'a pas marché
exit:
	btst	#6,ciapra(a4)
	bne	exit
error:
	bsr	Init_Drive

	bsr	restore_all
	rts			;retour au cli


;******************************************************

	rsreset
varsize	rs.w	0
head	rs.w	1	;tête de lecture (0-1)
essais	rs.w	1	;essais en cas d'erreur (max 4)
dvarsize	rs.w	0	;
track	rs.w	1	;piste (0 à 79) 

;**************** CIA A *******************************
dskrdy	=	5	;drive prêt
dsktrk0	=	4	;piste 0 atteinte
dskprot	=	3	;disquette protégée en écriture
dskchng	=	2	;disquette changée
ciapra	=	$0000

;**************** CIA B *******************************
dskmtr	=	7	;contrôle moteur
dsksel3	=	6	;sélection DF3:
dsksel2	=	5	;sélection DF2:
dsksel1	=	4	;sélection DF1:
dsksel0	=	3	;sélection DF0:
dskside	=	2	;sélection de la face
dskdir	=	1	;direction
dskstep	=	0	;déplacement d'une piste
ciaprb	=	$0100


;********************************************************
; Routines diverses et variées, pas très appréciées de
; Commodore inc. ...

save_all:
	move.b	$BFD100,save_ciabprb
	move.b	#%10000111,$BFD100
	move.l	4,a6
	jsr	-132(a6)	Forbid()
	jsr	-150(a6)	SuperState()
	move.l	d0,save_user
	move.w	sr,save_sr
	ori	#$700,sr
	move.l	$6c,save_vecteur_irq
	move.w	$DFF01C,save_intena
	or.w	#$C000,save_intena
	move.w	$DFF002,save_dmacon
	or.w	#$8100,save_dmacon
	rts

restore_all:
	move.b	save_ciabprb,$bfd100
	move.w	#$7FFF,$DFF09A
	move.l	save_vecteur_irq,$6C
	move.l	4,a6
	move.w	sr,d0
	and.w	#$F8FF,d0
	and.w	#$0700,save_sr
	or.w	save_sr,d0
	move.w	d0,sr
	move.l	save_user,d0
	jsr	-156(a6)	UserState (SysStack D0)
	move.w	save_intena,$DFF09A
	move.w	#$7FFF,$DFF096
	move.w	save_dmacon,$DFF096
	lea	name_glib,a1
	moveq	#0,d0
	jsr	-552(a6)	OpenLibrary (LibName A1, Version D0)
	move.l	d0,a0
	move.l	38(a0),$DFF080
	clr.w	$DFF088
	move.l	d0,a1
	jsr	-414(a6)	CloseLibrary (Library A1)
	jsr	-138(a6)	Permit()
	rts

save_vecteur_irq 	dc.l	0
save_intena 	dc.w	0
save_dmacon 	dc.w	0
save_user		dc.l	0
save_sr		dc.w	0
save_ciabprb 	dc.b	0
name_glib 	dc.b	"graphics.library"
	even


;******************************************************
; Lecture d'une piste.
; D0=track #
; A0=adresse

ReadTrack:
	bsr	MotorOn
	bsr	readthistrack
	bsr	stopdrive
	rts


;**************** START DRIVE *************************
; Routines disque proprement dites...

; place la têtes de lecture au dessus de la piste 0 , face 0
Init_Drive:
	bsr	MotorOn
	bsr	Seek0
	bsr	stopdrive

Seek0:	bset	#dskdir,ciaprb(a3)	;dir = > piste 0
	bset	#dskside,ciaprb(a3)	;face = lower (0)
.seek0:	btst	#dsktrk0,ciapra(a4)	;piste 0 atteinte
	beq	.track0		;oui
	bsr	moveheads		;sinon déplace les têtes
	bra	.seek0
.track0:	rts	

MotorOn:	
	lea	$BFD000,a3	;CIA-B
	lea	$BFE001,a4	;CIA-A
	bset	#dsksel0,ciaprb(a3)	;non sélection du lecteur 0	
	bclr	#dskmtr,ciaprb(a3)	;moteur mis en marche
	bclr	#dsksel0,ciaprb(a3)	;sélection lecteur 0
.wait:	btst	#dskrdy,ciapra(a4)	;test de dskrdy
	bne	.wait
	rts

stopdrive:
	bset	#dsksel0,ciaprb(a3)	;déselection du lecteur 0
	bset	#dskmtr,ciaprb(a3)	;arrêt du moteur
	bset	#dskmtr,ciaprb(a3)	;arrêt du moteur (bis)
	bclr	#dsksel0,ciaprb(a3)	;sélection du lecteur 0
	rts


;******************************************************
; fournit l'impulsion STEP au lecteur
; suivie du délai obligatoire

moveheads:
	bset	#dskstep,ciaprb(a3)	;step = high
	nop
	nop
	nop
	bclr	#dskstep,ciaprb(a3)	;step = low	
	nop
	nop
	nop
	bset	#dskstep,ciaprb(a3)	;step = high
softdelay:
	move.w	#5000,d0
	dbra	d0,*
	rts


;******************************************************
; Positionne les têtes de lecture/écriture au dessus
; de la piste désignée par d0
; Ici, les pistes sont numerotées de 0 a 159. La face 0
; contient les pistes paires, la face 1, les pistes impaires

seekthistrack:
	moveq	#1,d2
	bset	#dskside,ciaprb(a3)	;face 0
	clr.w	head(a5)
	lsr.w	#1,d0
	bcc	.lowerside
	bclr	#dskside,ciaprb(a3)	;face 1
	add.w	#1,head(a5)
.lowerside:
	move.w	d0,d1
	sub.w	track(a5),d0	;dans quelle direction aller?
	beq	.seekok		;c'est ok on y est
	bpl	.seekfoward
.seekbackward:
	bset	#dskdir,ciaprb(a3)	;vers le sillon 0
	neg.w	d2
	bra	.seekit
.seekfoward:
	bclr	#dskdir,ciaprb(a3)
.seekit:
	bsr	moveheads		;déplace les tetes d'une piste
	add.w	d2,track(a5)	;inc/dec les compteurs de pistes
	cmp.w	track(a5),d1	;piste demandée atteinte?
	bne	.seekit
.seekok:
	rts


;******************************************************
; Lecture de la piste d0 dans le tampon pointé par a0
; Cette routine recherche la bonne piste (seek), la lit et décode les MFM

readthistrack:
	movem.l	a0-a6/d1-d5,-(sp)
	lea	dskvars(pc),a5	;a5=variables locales
	clr.w	essais(a5)	;nombre d'essais = 0
	bsr	seekthistrack	;recherche de la piste à lire
	lea	$DFF01A,a4	;DSKBYTR
	lea	$BFDD00,a6
_retry:
	move.w	#$8010,$DFF096	;Autorisation du DMA disquette
	move.w	#$7F00,$DFF09E	;Effacement du Bit disquette

	move.w	#$9500,$DFF09E	;MSB on
	move.w	#$8000,$DFF024	;Préparer la transmission

	move.b	(a6),D0
.Index1:	move.b	(a6),D0	;Attendre le trou d'Index
	btst	#4,D0
	beq.s	.Index1
	move.w	(a4),d1

	move.w	#$1800,d1
.WaitSync	move.w	(a4),d2	;Attente du sync
	bpl.s	*-2
	cmp.b	#$44,d2
	beq.s	.NextSync
.Retry	dbra	d1,.WaitSync
	bra	_Error
.NextSync	move.w	(a4),d2
	bpl.s	*-2
	cmp.b	#$89,d2
	bne.s	.Retry

	move.l	#(64+1024)*11,d1
.Read	move.w	(a4),d2
	bpl.s	*-2
	move.b	d2,(a0)+
	sub.l	#1,d1
	bne.s	.Read
;	btst	#4,(a6)
;	beq.s	.Read

_TrackEnd	move.w	#$4000,$DFF024
	movem.l	(sp)+,a0-a6/d1-d5
	clr.l	d0
	rts

_Error:	move.w	#$4000,$DFF024
	add.b	#1,essais(a5)
	cmp.b	#5,essais(a5)
	blt	_retry
	movem.l	(sp)+,a0-a6/d1-d5
	move.l	#-1,d0
	rts


;*************************************************
dskvars:	dcb.w	dvarsize
track2:	dcb.b	(64+1024)*11+$400

	end
