 LIST P=16F687, R=DEC, ST=OFF, MM=OFF
 INCLUDE "p16F687.inc"

 __CONFIG _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CP_OFF & _CPD_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC 

#define BAUD 9600				; baud rate
#define XTAL 20					; crystal freq in MHz
#define X ((XTAL*1000000)/(BAUD*64))-1
#define CS PORTC,6				; chip select pin
#define SDI TRISB^0x80,4		; SDI pin
#define SDO TRISC^0x80,7		; SDO pin
#define SCL TRISB^0x80,6		; SCL pin

 
;  Data segment
 CBLOCK 0x20                  
 ind, msgNo, temp, cnt:2		; local variables
 cmd							; MMC command code
 arg:4							; MMC command argument
 resp							; MMC response
 fat:2, dir:2, dat:2			; sectors of FAT16 file system
 cluster:2, fileLen:4			; starting cluster of file and its length
 bytes2Skip:2					; counter of # of bytes to skip
 skipCnt:4						; local skip counter
 currDirSectNo					; current dir sector number (at most 31)
 partType, sectPerClust
; sectorSize 
 ENDC

; Code segment
 ORG 0
	goto	main

 ORG 4
	retfie

msg1
	movf	ind, w
	addwf	PCL, f
	dt 13, 10, 13, 10, "UART module is running", 13, 10, 0
msg2
	movf	ind, w
	addwf	PCL, f
	dt "MMC module is active", 13, 10, 0
msg3
	movf	ind, w
	addwf	PCL, f
	dt " CMD0 is through", 13, 10, 0
msg4
	movf	ind, w
	addwf	PCL, f
	dt " CMD1 is through", 13, 10, 0
msg5
	movf	ind, w
	addwf	PCL, f
	dt " MMC error", 13, 10, 0
msg6
	movf	ind, w
	addwf	PCL, f
	dt " command accepted ", 13, 10, 0	

bin2hex
	andlw	0x0F
	addwf	PCL, f
	retlw	'0'
	retlw	'1'
	retlw	'2'
	retlw	'3'
	retlw	'4'
	retlw	'5'
	retlw	'6'
	retlw	'7'
	retlw	'8'
	retlw	'9'
	retlw	'A'
	retlw	'B'
	retlw	'C'
	retlw	'D'
	retlw	'E'
	retlw	'F'

printByte						; send a byte in WREG to UART in HEX
	movwf	temp				; and a space after it
	swapf	temp, f
	movf	temp, w
	call	bin2hex
	call	sendChar
	swapf	temp, f
	movf	temp, w
	call	bin2hex
	call	sendChar
	movlw	32
	call	sendChar
	return

newline							; start a new line on remote terminal
	movlw	13
	call 	sendChar
	movlw	10
	call	sendChar
	return

getNextChar						; aux. procedure for getting next char
	movf	msgNo, w			; of the message string with number in
	addwf	PCL, f				; msgNo
	return
	goto	msg1
	goto	msg2
	goto	msg3
	goto	msg4
	goto	msg5
	goto	msg6
	goto	msg7
	goto	msg8
	goto	msg9

sendChar						; send char in WREG over UART
	btfss	PIR1, TXIF			; TX buffer is full?
	 goto	$-1					; YES - wait
	movwf	TXREG				; send out byte
	return

sendString						; outputs string with number in WREG
	movwf	msgNo				; set message number
	clrf	ind					; start the message
	
	movf	ind, w				; next char index
	call	getNextChar			; get next char
	addlw	0					; set bit Z in STATUS
	btfsc	STATUS, Z			; end of string?
	 return						; YES - return
	
	call	sendChar
	incf	ind, f				; get to the next char
	goto	sendString+2
	return 

spi_io							; send/receive byte via SPI
	movwf	SSPBUF				; put data to send in WREG into SSPBUF
	btfss	SSPCON, WCOL		; data sent?
	 goto	$+3					; YES - proceed
	bcf		SSPCON, WCOL		; NO - reset WCOL and try again
	goto	$-4					

	bsf		STATUS, RP0			; switch to BANK 1
	btfss	SSPSTAT ^ 0x80, BF	; buffer full?
	 goto	$-1					; NO - wait
	bcf		STATUS, RP0			; back to BANK 0

	movf	SSPBUF, w			; return the received data in WREG
	return

composeByteAddr
	movlw	9
	movwf	temp				; multiply the sector # by 512
	bcf		STATUS, C			; to get the byte address
	rlf		arg, f
	rlf		arg+1, f
	rlf		arg+2, f
	rlf		arg+3, f
	decfsz	temp, f
	 goto	$-6
	return

sendMMC							; send 48-bit MMC instruction
	movlw	0xFF				; sending of this byte not formally documented
	call	spi_io				; but it does not work without it
	movf	cmd, w				; send the command byte
	call	spi_io
	movf	arg+3, w			; send 4 argument bytes
	call	spi_io
	movf	arg+2, w
	call	spi_io
	movf	arg+1, w
	call	spi_io
	movf	arg, w
	call	spi_io

	movlw	0x40				; setup CRC7: it is 0xFF for all instructions
	subwf	cmd, w				; except CMD0, for which it must be 0x95
	movlw	0xFF
	btfsc	STATUS, Z
	 movlw	0x95
	call	spi_io

	movlw	0x41				; setup waiting time: it is 80 cycles for 
	subwf	cmd, w				; all instructions except of CMD1, for
	movlw	255					; which it must be 2
	btfsc	STATUS, Z
	 movlw	2	
	movwf	cnt					; setup response waiting counter
wait_resp						; wait for response for at most cnt cycles
	movlw	0xFF				; waiting for MMC responce
	call	spi_io
	subwf	resp, w				; expected responce?
	btfsc	STATUS, Z
	 retlw 	0					; YES - return
	decfsz	cnt, f				; waiting period is over?
	 goto	wait_resp			; NO - keep waiting
	retlw	1		

initMMC							; initialize SPI module and MMC
	bcf		STATUS, RP1	
  	bsf    	STATUS, RP0			; switch to BANK 1

	bsf		SDI					; setup I/O ports
	bcf		SDO
	bcf		SCL

	bcf		SSPSTAT ^ 0x80, SMP	; input is ready at the end of clock
	bcf		SSPSTAT ^ 0x80, CKE	; 

	bcf		STATUS, RP0			; switch to BANK 0
	bsf		SSPCON, CKP			; idle state for clock is high
	bsf		SSPCON, SSPM1		; set lowest speed FOSC/64
	bsf		SSPCON, SSPEN		; enable SPI master

	bsf		CS					; disable MMC
	movlw	10
	movwf	cnt					; send 80 dummy clocks	
	movlw	0xFF
	call	spi_io
	decfsz	cnt, f	
	 goto	$-3
	bcf		CS					; enable MMC

	movlw	0x40				; send CMD0
	movwf	cmd
	clrf	arg
	clrf	arg+1
	clrf	arg+2
	clrf	arg+3
	movlw	1					; expected response
	movwf	resp
	call	sendMMC
	addlw	0					; set Z flag
	movlw	3					; message of success
	btfss	STATUS, Z
	 movlw	5					; report an error
	call	sendString

	movlw	0x41				; send CMD1
	movwf	cmd
	clrf	arg
	clrf	arg+1
	clrf	arg+2
	clrf	arg+3
	clrf	resp				; expected response
	call	sendMMC
	addlw	0
	btfss	STATUS, Z
	 goto	$-10
	movlw	4					; message of success
	btfss	STATUS, Z
	 movlw	5
	call	sendString
	bcf		SSPCON, SSPM1		; set speed FOSC/4
	return

initUART						; setup the UART module
	bcf		STATUS, RP1	
  	bsf    	STATUS, RP0			; switch to BANK 1
	movlw 	X					; load the baud rate generator
	movwf	SPBRG ^ 0x80
	bsf		TXSTA ^ 0x80, TXEN	; enable TX for 8 data bits
	bcf		STATUS, RP0			; switch to BANK 0
	bsf		RCSTA, SREN			; enable USART for 8 data bits
	bsf		RCSTA, SPEN			; this automatically configures TX and RX pins

	movlw	1					; display message1
	call	sendString			; if UART is working
	return

skipBytes						; read number of bytes in cnt:cnt+1
	movf	skipCnt, w			; skip the bytes
	iorwf	skipCnt+1, w
	btfsc	STATUS, Z
	 return						; end of skip
	movlw	0xFF
	call	spi_io				; get data byte
	movf	skipCnt, f			; decrement 16-bit counter
	btfsc	STATUS, Z
	 decf	skipCnt+1, f
	decf	skipCnt, f
	goto	skipBytes

skipRest514
	movf	skipCnt+2, w		; # of remaining bytes in sector to skip
	sublw	LOW 514				; skipCnt = 514 - skipCnt   (16 bits)
	movwf	skipCnt
	movf	skipCnt+3, w
	btfss	STATUS, C
	 addlw	1
	sublw	HIGH 514
	movwf	skipCnt+1
	call	skipBytes			; skip to the end of sector	
	return

skipRest512						; skip 512 - skipCnt:2 bytes till the
	movf	skipCnt+2, w		; end of current sector
	sublw	LOW 512				; skipCnt = 512 - skipCnt   (16 bits)
	movwf	skipCnt
	movf	skipCnt+3, w
	btfss	STATUS, C
	 addlw	1
	sublw	HIGH 512
	movwf	skipCnt+1
	call	skipBytes			; skip to the end of sector	
	return

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
nextFile						; scans the dir list and returns the starting
	call	getNextDirSector
	movlw	0x51				; cluster of the next file
	movwf	cmd					; arg must point to FAT1
	movlw	0xFE				; expected response
	movwf	resp
	call	sendMMC				; send command for sector reading
	addlw	0
	btfss	STATUS, Z
	 retlw	1					; error

	movf	bytes2Skip, w		; bytes2Skip = 0?	
	iorwf	bytes2Skip+1, w
	btfsc	STATUS, Z
	 goto	read_first_byte

	movf	bytes2Skip, w		; setup local skip bytes counter
	movwf	skipCnt				; set up the counter of # bytes to skip
	movf	bytes2Skip+1, w
	movwf	skipCnt+1
skip
	call	skipBytes			; and do the skip
	btfsc	bytes2Skip+1, 1		; less than 512 bytes to skip?
	 goto	sector_end			; NO - end of sector

	incf	bytes2Skip, f		; increment the global skip number
	btfsc	STATUS, Z
	 incf	bytes2Skip+1, f

read_first_byte
	movlw	0xFF
	call	spi_io				; get the first byte of the 32-byte record
	addlw	0
	btfsc	STATUS, Z			; end of the dir list?
 	 goto	start_over			; YES - end of dir list	
	movwf	temp

	movlw	31					; update skip number
	addwf	bytes2Skip, f		; so that it points to the next dir record		
	btfsc	STATUS, C
	 incf	bytes2Skip+1, f

	movf	temp, w	
	sublw	0xE5				; is it deleted file?
	btfss	STATUS, Z
	 goto 	not_deleted			; NOT deleted - proceed

	movlw	31					; YES deleted - skip till the end of this record
	movwf	skipCnt
	clrf	skipCnt+1
	goto	skip

not_deleted						; check the record starting cluster
	movlw	25
	movwf	skipCnt				; skip to the cluster word position
	clrf	skipCnt+1
	call	skipBytes

	movlw	0xFF
	call	spi_io				; get cluster number	
	movwf	cluster
	movlw	0xFF
	call	spi_io				
	movwf	cluster+1

	iorwf	cluster, w
	btfss	STATUS, Z			; cluster = 0 (fake record)?
	 goto	real_record			; NO - proceed
	movlw	4
	movwf	skipCnt				; YES - get to the next record
	clrf	skipCnt+1
	goto	skip

real_record
	movlw	0xFF				; get the file length	
	call	spi_io
	movwf	fileLen
	movwf	temp
	movlw	0xFF
	call	spi_io
	movwf	fileLen+1
	iorwf	temp, f
	movlw	0xFF
	call	spi_io
	movwf	fileLen+2
	iorwf	temp, f
	movlw	0xFF
	call	spi_io
	movwf	fileLen+3
	iorwf	temp, w
	btfsc	STATUS, Z			; zero file length?
	 goto	skip+1				; YES - get to the next record

skip_rest	
	movf	bytes2Skip, w
	movwf	skipCnt+2
	movf	bytes2Skip+1, w
	movwf	skipCnt+3
	call	skipRest514
	btfss	bytes2Skip, 1		; end of current dir sector?
	 retlw	0
	incf	currDirSectNo, f
	clrf	bytes2Skip
	clrf	bytes2Skip+1
	retlw	0

sector_end
	incf	currDirSectNo, f
	clrf	bytes2Skip
	clrf	bytes2Skip+1
	goto	nextFile	

start_over
	movf	bytes2Skip, w
	movwf	skipCnt+2
	movf	bytes2Skip+1, w
	movwf	skipCnt+3
	call	skipRest514
	movlw	31					; simulate scanning the dir list
	movwf	currDirSectNo		; from the very beginning
	goto	nextFile			; start over

getNextDirSector
	movf	dir, w
	movwf	arg
	movf	dir+1, w
	movwf	arg+1
	clrf	arg+2
	clrf	arg+3

	movlw	31
	subwf	currDirSectNo, w
	btfss	STATUS, Z			; if this number is >=31, the dir list is over
	 goto	nextDirSect

	clrf	currDirSectNo		; start from the beginning of the dir list
	call	composeByteAddr
	movlw	32					; in this case bytes2Skip = 32
	movwf	bytes2Skip
	clrf	bytes2Skip+1
	return

nextDirSect
	movf	currDirSectNo, w	; add curr dir sect # to arg (16-bit op)
	addwf	arg, f
	btfsc	STATUS, C
	 incf	arg+1, f
	call	composeByteAddr	
	return

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
nextCluster						; get the next file cluster #
	movf	fat+1, w			; arg+1 = fat starting sector
	movwf	arg+1
	movf	fat, w
	movwf	arg
	movf	cluster+1, w		; W = # sector in FAT containing the current
	addwf	arg, f				; cluster number
	btfsc	STATUS, C			; add this number to the starting
	 incf	arg+1, f			; FAT sector #
	clrf	arg+2
	clrf	arg+3
	call	composeByteAddr		; sector address containing the next cluster # 

	bcf		STATUS, C			; cluster = (offset of cluster # position
	rlf		cluster, w			; in a sector) / 2
	movwf	skipCnt
	movwf	skipCnt+2
	rlf		cluster+1, w		; so we multiply it by 2 to get byte offset
	movwf	skipCnt+1
	movwf	skipCnt+3

	movlw	0x51				; start reading sector
	movwf	cmd
	movlw	0xFE				
	movwf	resp
	call	sendMMC

	call	skipBytes			; read next file cluster # from FAT
	movlw	0xFF
	call	spi_io
	movwf	cluster
	movlw	0xFF
	call	spi_io
	movwf	cluster+1	
	call	skipRest512			; skip bytes till the sector end
	return

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
readSector						; read sector in arg and dumps it to UART
	movlw	0x51				; send CMD
	movwf	cmd
	movlw	0xFE				; expected response
	movwf	resp
	call	sendMMC
	addlw	0
	btfss	STATUS, Z
	 retlw	1					; error

	clrf	skipCnt
	clrf	skipCnt+1
	movlw	0xFF
	call	spi_io
 call	sendChar
	incf	skipCnt, f
	btfsc	STATUS, Z
	 incf	skipCnt+1, f
	btfss	skipCnt+1, 1
	 goto	$-7

	movlw	0xFF
	call	spi_io
	movlw	0xFF
	call	spi_io
	retlw	0

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
dumpSector						; read sector in arg and dumps it to UART
	movlw	0x51				; send CMD
	movwf	cmd
	movlw	0xFE				; expected response
	movwf	resp
	call	sendMMC
	addlw	0
	btfss	STATUS, Z
	 retlw	1					; error

	movlw	0xFE				; check if fileLen >= 512
	andwf	fileLen+1, w
	iorwf	fileLen+2, w
	iorwf	fileLen+3, w		; Z-bit is set iff fileLen < 512	
	btfss	STATUS, Z
	 goto	read_whole_sect

	movf	fileLen, w			; in this case fileLen is the number of
	movwf	skipCnt				; bytes to read from this sector
	movwf	skipCnt+2
	movf	fileLen+1, w
	movwf	skipCnt+1
	movwf	skipCnt+3
	bsf		fileLen+3, 7		; mark file length as negative

	goto	data_loop			; (needed for dumpFileCluster() method)

read_whole_sect
	clrf	skipCnt				; skipCnt = 512 (16 bit)
	clrf	skipCnt+2
	movlw	2	
	movwf	skipCnt+1			
	movwf	skipCnt+3

	movlw	2					; 24-bit subtract 512 from fileLen
	subwf	fileLen+1, f		
	clrf	temp	
	clrw
	btfss	STATUS, C
	 incfsz	temp, w		
	  subwf	fileLen+2, f
	clrf	temp
	clrw
	btfss	STATUS, C
	 incfsz	temp, w
	  subwf	fileLen+3, f		; subtraction is completed

data_loop
	movlw	0xFF
	call	spi_io				; get data byte
; call	printByte				; send it to PC
 call	sendChar

	movf	skipCnt, w			; decrement the loop counter
	btfsc	STATUS, Z
	 decf	skipCnt+1, f
	decf	skipCnt, f
	movf	skipCnt, w
	iorwf	skipCnt+1, w		; and check it for 0
	btfss	STATUS, Z
	 goto	data_loop        
	call	skipRest514			; skip bytes till the end of sector
	retlw	0

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
setBlockSize
	movlw	0x50				; send CMD
	movwf	cmd
	clrf	arg					; arg = 512
	movlw	2
	movwf	arg+1
	clrf	arg+2
	clrf	arg+3
	clrf	resp				; expected response
	call	sendMMC
	addlw	0
	btfss	STATUS, Z
	 retlw	1					; error
	retlw	0

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
dumpFileCluster
	movlw	2					; get real cluster #
	subwf	cluster, w			; subtract 2 (16-bit operation)
	movwf	arg
	clrw
	btfss	STATUS, C
	 addlw	1
	subwf	cluster+1, w		; compose sector #
	movwf	arg+1				
	clrf	arg+2				
	clrf	arg+3
	
	movf	sectPerClust, w		; multiply cluster # by the number of
	movwf	cnt					; sectors in cluster (sectPerClust)
	decf	cnt, f				; since this is always a power of 2
	btfsc	STATUS, Z			; left shifts are used instead of multiplication
	 goto	$+6
	bcf		STATUS, C
	rlf		arg, f				; the resulting # might be 24-bit, if the
	rlf		arg+1, f 			; cluster number is above the 32Mb area
	rlf		arg+2, f			; but it is never 32-bit for small MMC cards
	goto	$-7

	movf	dat, w				; add to the sector offset the number
	addwf	arg, f				; of the first sector in the data area
	movf	dat+1, w
	btfsc	STATUS, C
	 incfsz	dat+1, w
	  addwf	arg+1, f
	clrw
	btfsc	STATUS, C
	 addlw	1					; here the correct C bit is not needed
	addwf	arg+2, f
	call	composeByteAddr		; byte address of the firsts sector in cluster	

	movf	sectPerClust, w		; LOOP OVER sectors in cluster
	movwf	cnt+1				; sector counter

sect_loop
	btfsc	fileLen+3, 7		; file length negative?
	 return

	call	dumpSector			; No -proceed
	movlw	2					; get to the next sector by adding 512
	addwf	arg+1, f			; to its byte address
	clrw
	clrf	temp				; since the LS byte of this address is
	btfsc	STATUS, C			; always 0, a 24-bit addition is used
	 incfsz	temp, w
	  addwf	arg+2, f
	clrw
	btfsc	STATUS, C
	 addlw	1					; here the correct C bit is not needed
	addwf	arg+3, f

	decfsz	cnt+1, f			; update sector counter 
	 goto	sect_loop			; and loop back if needed
	return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
main
	bsf		STATUS, RP1			; switch to BANK 2
	clrf	ANSEL ^ 0x100		; set all pins digital
	clrf	ANSELH ^ 0x100

	bcf		STATUS, RP1	
  	bsf    	STATUS, RP0			; switch to BANK 1
	clrf	TRISA ^ 0x80		; set all potrs for output
	clrf	TRISB ^ 0x80		; to prevent oscillation
	clrf	TRISC ^ 0x80
	bcf		STATUS, RP0			; switch to BANK 0

	call	initUART			; setup the USART module
	call	initMMC				; setup the SSP module and initialize MMC

; STEP 1: read MBR
	clrf	arg					; read MBR sector 0
	clrf	arg+1				
	clrf	arg+2
	clrf	arg+3
	movlw	0x51		
	movwf	cmd
	movlw	0xFE				; expected response
	movwf	resp
	call	sendMMC				; send command for sector reading

	movlw	LOW 0x1C2			; read partition type
	movwf	skipCnt
	movlw	HIGH 0x1C2
	movwf	skipCnt+1		
	call	skipBytes
	movlw	0xFF
	call	spi_io
	movwf	partType			; save partition type code
	movlw	3					; skip next 3 bytes
	movwf	skipCnt
	clrf	skipCnt+1
	call	skipBytes

	movlw	0xFF				; read the gap between the MBR sector and the
	call	spi_io				; first partition sector (in sectors)
	movwf	arg	
	movwf	fat
	movlw	0xFF
	call	spi_io
	movwf	arg+1
	movwf	fat+1
	movlw	160					; skip 158 + 2 bytes till the end of sector
	movwf	skipCnt
	clrf	skipCnt+1
	call	skipBytes
	call	composeByteAddr		; byte addr. of VBR of partition 1

; STEP 2: read VBR
	movlw	0x51				; read VBR sector
	movwf	cmd
	movlw	0xFE				; expected response
	movwf	resp
	call	sendMMC				; send command for sector reading

	movlw	0xD					; read # of sectors per cluster # of reserved
	movwf	skipCnt				; sectors after VBR
	clrf	skipCnt+1
	call	skipBytes
	movlw	0xFF
	call	spi_io
	movwf	sectPerClust

	movlw	0xFF
	call	spi_io
	addwf	fat, f
	clrf 	temp				; save C bit
	btfsc	STATUS, C
	 incf	temp, f
	movlw	0xFF
	call	spi_io
	addwf	temp, w
	addwf	fat+1, f			; starting sector of FAT1 is computed

	movlw	6					; skip next 6 bytes
	movwf	skipCnt
	clrf	skipCnt+1
	call	skipBytes
	movlw	0xFF				; read # sectors per FAT
	call	spi_io	
	movwf	skipCnt
	movlw	0xFF	
	call	spi_io	
	movwf	skipCnt+1
	
	bcf		STATUS, C
	rlf		skipCnt, f			; multiply it by 2 (for 2 copies of FAT)
	rlf		skipCnt+1, f
	movf	skipCnt, w
	addwf	fat, w
	movwf	dat
	movwf	dir
	movf	skipCnt+1, w
	btfsc	STATUS, C			; computing the position of the directory list
	 addlw	1					; it occupies 32 secors (16Kb)
	addwf	fat+1, w
	movwf	dir+1				; starting sector of dir list is computed
	movwf	dat+1
	
	movlw	32
	addwf	dat, f
	btfsc 	STATUS, C
	 incf	dat+1, f			; starting sector of the data area
	movlw	LOW 490
	movwf	skipCnt
	movlw	HIGH 490
	movwf	skipCnt+1
	call	skipBytes			; finish working with VBR

; STEP 3: loop over the directory list
	movlw	31
	movwf	currDirSectNo		; start scanning dir list from the beginning

files_loop	
	call	nextFile			; get starting cluster of the next file
								; in the dir list and its length

; STEP 4: loop over the file cluster chain
cluster_loop
	call	dumpFileCluster	

	call	nextCluster			; get next file cluster
	movlw	0xFF				; check for last file cluster
	xorwf	cluster+1, w
	movwf	temp	
	movlw	0xFF
	xorwf	cluster, w
	iorwf	temp, w
	btfss	STATUS, Z			; last cluster?
	 goto	cluster_loop		; NO - proceed with the next file cluster	
	goto	files_loop				; prev file is over, get the next one


 END
