USB-Floppy: USB schreiben

Ausgangspunkt ist ein ATmega32U4 mit 16-MHz-Quarz, verbaut in Arduino Leonardo und Nachfolgern, etwa dem sehr preiswerten Pro Micro. Für die zeitkritischen Routinen kommt nur Assembler in Frage. Zur Kombination mit gcc wird der Gnu-Assembler-Dialekt gas verwendet, nicht avrasm.

Gestückelt

So ungefähr sollte es aussehen:

// Als Makro, Unterprogrammaufrufe sind beim AVR lahm und fressen 9 Takte
// Vorgehaltene Register:
// R16 = Word-Zähler 32..0, -1 = Commit, -2 = nächster Datenblock
// R3 = USB-Block-Zähler, 7..0 (bei Sektorlänge 512 Byte)
// X = Datenquelle (Sektordaten) im RAM
// UENUM steht bereits richtig
.macro usb_write retlbl	;Rücksprungziel als Argument
	subi	r16,1	;herunterzählen mit Carry-Flag
	brmi	1f	;(negativ)
	ld	r24,X+
	sts	UEDATX,r24
	ld	r24,X+
	sts	UEDATX,r24
	rjmp	\retlbl	;Σ 12 Takte (ohne Ansprung)
1:	brcs	2f
	ldi	r16,-2	;-2 wiederherstellen
	sbrc	r3,7	;Weitere USB-Blöcke?
	 rjmp	\retlbl	;Σ 8 Takte (nein wenn negativ)
	lds	r24,UEINTX
	sbrc	r24,7	;wenn FIFO bereit …
	 ldi	r16,32	;… 32 WORDs schreiben lassen
	rjmp	\retlbl	;Σ 13 Takte
2:	ldi	r24,0x7E
	sts	UEINTX,r24	;Commit
	dec	r3
	rjmp	\retlbl	;Σ 11 Takte
.endm