⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpc_fs.asm

📁 8051 mp3 very good for using
💻 ASM
字号:
;-----------------------------------------------;
; FS - Load BBT into work area
;
; Call: none
; Ret:  Z=1: Successful, Bbt = valid
;       Z=0: Unformatted

load_bbt:
	 rcall	clr_page	; Page# = 0
	 rcall	sm_rd_page	; Read 1st page
	ldiw	Y,Bbt		; BBT buffer to be stored
	clr	r1		; Clear CRC reg
	clr	r2		; /
	ldi	_Loop,NBBT*2	; 
	 rcall	sm_read		;--- Loading loop
	st	Y+,r16		; 
	 rcall	mk_crc		; 
	dec	_Loop		; 
	brne	PC-4		; /
	 rcall	sm_read		; Check CRC
	 rcall	mk_crc		; 
	 rcall	sm_read		; 
	 rcall	mk_crc		; 
	or	r1,r2		; /
	 rcall	sm_read		; Check Mark
	subi	r16,0x55	; 
	or	r1,r16		; /
	ret



;-----------------------------------------------;
; FS - Save BBT into Medium
;
; Call: none
; Ret:  C=0: successful
;       C=1: error

save_bbt:
	 rcall	clr_page	; Page# = 0
	 rcall	sm_wr_set	; Ready to write
	ldiw	Y,Bbt		; BBT buffer to be saved
	clr	r1		; Clear CRC reg
	clr	r2		; /
	ldi	_Loop,NBBT*2	; Save BBT buffer
	ld	r16,Y+		; 
	 rcall	mk_crc		; 
	 rcall	sm_write	; 
	dec	_Loop		; 
	brne	PC-4		; /
	clr	r16		; Write CRC
	 rcall	mk_crc		; 
	 rcall	mk_crc		; 
	mov	r16,r2		; 
	 rcall	sm_write	; 
	mov	r16,r1		; 
	 rcall	sm_write	; /
	ldi	r16,0x55	; Write Mark
	 rcall	sm_write	; /

	rjmp	sm_wr_start	; Write BBT Page



;-----------------------------------------------;
; FS - Load TOC into work area
;
; Call: none
; Ret:  Tracks, IdxTbl, CRC

load_toc:
	 rcall	clr_page	; Page# = 1
	 rcall	next_page	; /
	 rcall	sm_rd_page	; Read page
	ldiw	Y,Tracks	; TOC buffer and CRC to be laod
	clr	r1		; Clear CRC reg
	clr	r2		; /
	ldi	_LoopL,low(1+NTRK*6+2); 
	ldi	_LoopH,high(1+NTRK*6+2); 
	 rcall	sm_read		;--- Loading loop
	st	Y+,r16		; 
	 rcall	mk_crc		; 
	subi	_LoopL, 1	; 
	sbci	_LoopH, 0	; 
	brne	PC-5		; /
	or	r1,r2		; Check CRC
	breq	PC+4		; /
	sts	Tracks,_0	; When invalid TOC, clear TOC
	ret



;-----------------------------------------------;
; FS - Save TOC into Medium
;
; Call: Tracks, IdxTbl = TOC data for save
; Ret:  none

save_toc:
	 rcall	clr_page	; Page# = 1
	 rcall	next_page	; /
	 rcall	sm_wr_set	; Ready to write
	ldiw	Y,Tracks	; Write TOC
	clr	r1		; Clear CRC reg
	clr	r2		; /
	ldi	_LoopL,low(1+NTRK*6); 
	ldi	_LoopH,high(1+NTRK*6); 
	ld	r16,Y+		;--- Saving loop 
	 rcall	mk_crc		; 
	 rcall	sm_write	; 
	subi	_LoopL, 1	; 
	sbci	_LoopH, 0	; 
	brne	PC-5		; /
	clr	r16		; Make and add CRC
	 rcall	mk_crc		; 
	 rcall	mk_crc		; 
	mov	r16,r2		; 
	 rcall	sm_write	; 
	mov	r16,r1		; 
	 rcall	sm_write	; /
	rjmp	sm_wr_start	; Write TOC page



;-----------------------------------------------;
; FS - Check or Create CRC
;
;Call:	r2:r1 = 16bit working shift register
;       r16 = byte data for calc
;Ret:	r2:r1 = updated
;	r17 = broken

mk_crc:	push	_Loop
	push	r16
	ldi	_Loop,8		; Loop count = 8
	lsl	r16		;--- bit processing loop
	rol	r1		; Shift-In a bit into working reg.
	rol	r2		; /
	brcc	PC+5		; If pushed out a bit "1"
	ldi	r17,0b00010000	;  divide in CRC-CCITT
	eor	r2,r17		; 
	ldi	r17,0b00100001	; 
	eor	r1,r17		; /
	dec	_Loop		; End of loop ?
	brne	PC-9		;  no, continue
	pop	r16
	pop	_Loop
	ret



;-----------------------------------------------;
; FS - Add a track in sync xfer
;
; Call: none
; Ret:  none

xfer_track:
	 rcall	receive		; Receive number of pages to xfer
	mov	_LoopL,r16	; 
	 rcall	receive		; 
	mov	_LoopM,r16	; 
	 rcall	receive		; 
	mov	_LoopH,r16	; /
	 rcall	get_left	; Get number of free pages
	cp	_CntL,_LoopL	; Compare free pages and xfer pages
	cpc	_CntM,_LoopM	;  if free < xfer, exit
	cpc	_CntH,_LoopH	; 
	rjcs	xt_exit		; /

	 rcall	clr_page	; Initialize page parms
	mov	_CntL,_LoopL	; 
	mov	_CntM,_LoopM	; 
	mov	_CntH,_LoopH	; 
	lds	r16,SmPPB	; 
	mov	_PageL,r16	; 
	 rcall	sch_next	; /
	push	_PageL		; Push start page#
	push	_PageM		; 
	push	_PageH		; /
xt_mlp:				;---- Page xfer loop
	subi	_LoopL,byte1(1)	; End of xfer ?
	sbci	_LoopM,byte2(1)	;  yes, break
	sbci	_LoopH,byte3(1)	; 
	brcs	xt_upd		; /
	mov	r4,_PageL
	mov	r5,_PageM
	mov	r6,_PageH
	 rcall	sch_next	; Get next page to store
	mov	r1,_PageL
	mov	r2,_PageM
	mov	r3,_PageH
	mov	_PageL,r4
	mov	_PageM,r5
	mov	_PageH,r6
	 rcall	sm_wr_set	; Ready to write
	mov	_PageL,r1
	mov	_PageM,r2
	mov	_PageH,r3
	ldi	r16,0x06	; Send ACK
	 rcall	xmit		; /
	 rcall	sm_rcv512	; Receive 512 byte of page data with sync xfer
	mov	r16,_PageL	; Add link page#
	 rcall	sm_write	; 
	mov	r16,_PageM	; 
	 rcall	sm_write	; 
	mov	r16,_PageH	; 
	 rcall	sm_write	; /
	 rcall	sm_wr_start	; Start to write page
	rjmp	xt_mlp		; Continue

xt_upd:	pop	_PageH		; Pop start page#
	pop	_PageM		; 
	pop	_PageL		; /
	lds	r16,Tracks	; Tracks ++
	mov	r1,r16		; 
	inc	r1		; 
	sts	Tracks,r1	; /
	 rcall	get_trkidx	; Add track parms into TOC
	st	Y+,_PageL	; 
	st	Y+,_PageM	; 
	st	Y+,_PageH	; 
	st	Y+,_CntL	; 
	st	Y+,_CntM	; 
	st	Y+,_CntH	; /
	 rcall	sync_fs		; Update TOC on the medium

xt_exit:ldi	r16,0x04	; Send EOT
	rjmp	xmit		; /



;-----------------------------------------------;
; FS - Delete a track
; 
; Call: r16 = Track# to delete
; Ret:  none

del_track:
	lds	r1,Tracks	; If track# >= number of tracks, exit
	cp	r16,r1		; 
	brcs	PC+2		; 
	ret			; /
	dec	r1		; Tracks--
	sts	Tracks,r1	; /
	push	r16		; Push track#
	 rcall	get_trkpar	; Get track parms and TOC index
	sbiw	YL,6		; /
	push	YL		; Push TOC index
	push	YH		; /
	lds	r16,SmPPB	;--- Block erase loop
	or	_PageL,r16	; Get and push link block
	 rcall	sm_rd_page2	; 
	 rcall	sm_read		; 
	push	r16		; 
	 rcall	sm_read		; 
	push	r16		; 
	 rcall	sm_read		; 
	push	r16		; /
	 rcall	sm_erase	; Erase block
	pop	_PageH		; Pop link block
	pop	_PageM		; 
	pop	_PageL		; /
	lds	r16,SmPPB	; _CntX -= SmPPB+1
	inc	r16		; 
	sub	_CntL,r16	; 
	sbc	_CntM,_0	; 
	sbc	_CntH,_0	; /
	brcs	PC+2		; If _CntX > 0, continue
	brne	PC-21		; /
	pop	YH		; Pop TOC index and track#
	pop	YL		; 
	pop	_Loop		; /
	inc	_Loop		; Squeeze TOC entries
	cpi	_Loop,NTRK	; 
	brcc	PC+7		; 
	ldi	r17,6		; 
	ldd	r16,Y+6		; 
	st	Y+,r16		; 
	dec	r17		; 
	brne	PC-3		; 
	rjmp	PC-8		; /
	rjmp	sync_fs		; Update TOC on the medium



;-----------------------------------------------;
; FS - Delete all tracks
; 
; Call: none
; Ret:  none

del_alltrk:
	 rcall	clr_page	; Page = 0
	 rcall	sm_erase	; Erase all blocks
	 rcall	next_block	; 
	lds	r16,SmPages	; 
	lds	r17,SmPages+1	; 
	cp	_PageM,r16	; 
	cpc	_PageH,r17	; 
	brcs	PC-8		; /
	 rcall	save_bbt	; Restore BBT
	 rcall	load_toc	; Clear TOC
	sbi	PORTC,CE	; CE="H"
	ret



;-----------------------------------------------;
; FS - Change track order
;
; Call: r1 = source track#
;       r2 = destination track#
; Ret:  none

move_track:
	lds	r16,Tracks	; Check track validity
	cp	r1,r16		; 
	brcc	st_exit		; 
	cp	r2,r16		; 
	brcc	st_exit		; /
	mov	r16,r1		; Get source track index 
	 rcall	get_trkidx	; /
	sub	r1,r2		; Get distance and direction between two tracks
	breq	st_exit		;  when same track, exit.

	ldd	_PageL,Y+0	; Save source track information
	ldd	_PageM,Y+1	;
	ldd	_PageH,Y+2	;
	ldd	_CntL,Y+3	;
	ldd	_CntM,Y+4	;
	ldd	_CntH,Y+5	; /
	ldi	_Loop,6		; Shift TOC entries between two tracks
	tst	r1		;
	brmi	PC+7		;
	ld	r16,-Y		;
	std	Y+6,r16		;
	dec	_Loop		;
	brne	PC-3		;
	dec	r1		;
	rjmp	PC+6		;
	ldd	r16,Y+6		;
	st	Y+,r16		;
	dec	_Loop		;
	brne	PC-3		;
	inc	r1		;
	brne	PC-14		; /
	std	Y+0,_PageL	; Restore source track informatin
	std	Y+1,_PageM	;
	std	Y+2,_PageH	;
	std	Y+3,_CntL	;
	std	Y+4,_CntM	;
	std	Y+5,_CntH	; /
	 rcall	sync_fs		; Update TOC on the medium
st_exit:
	ret


;-----------------------------------------------;
; FS - Get track start and length
; 
; Call: r16 = Track#
; Ret:  _PageX = Track start page
;       _CntX = Track length
;	r17 = broken

get_trkpar:
	 rcall	get_trkidx	; Get track pointer
	ld	_PageL,Y+	; Load track parms
	ld	_PageM,Y+	; 
	ld	_PageH,Y+	; 
	ld	_CntL,Y+	; 
	ld	_CntM,Y+	; 
	ld	_CntH,Y+	; /
	ret

get_trkidx:
	ldiw	Y,IdxTbl	; Get pointer of track index
	lsl	r16
	mov	r17,r16
	lsl	r16
	add	r16,r17
	add	YL,r16
	adc	YH,YH
	ret



;-----------------------------------------------;
; FS - Check whether current block is good
;
; Call:  _PageX = Page(block) for checked
; Ret:   r16-r19, X = broken
;        Z = 0:good, 1:bad, 

chk_bad:
	 rcall	get_block	; Get current block#
	ldiw	X,Bbt		; Search same or large block number
	ld	r18,X+		; 
	ld	r19,X+		; 
	sub	r18,r16		; 
	sbc	r19,r17		; 
	brcs	PC-4		; /
	or	r18,r19		; Block is match ?
	ret



;-----------------------------------------------;
; FS - Get number of pages used
;
; Call:	<none>
; Ret:	_CntX = number of total pages

get_total:
	 rcall	clr_page	; Clear pages
	ldiw	Y,Tracks	; TOC
	ld	r16,Y+		; r16 = number of tracks
	tst	r16		;  End of tracks ?
	brne	PC+2		;   no, continue
	ret			;   yes, return
	ldd	r17,Y+3		;  add a track size
	add	_CntL,r17	;
	ldd	r17,Y+4		;
	adc	_CntM,r17	;
	ldd	r17,Y+5		;
	adc	_CntH,r17	;  /
	dec	r16		;  tracks--;
	adiw	YL,6		;  next track
	rjmp	PC-11



;-----------------------------------------------;
; FS - Get number of left pages
; 
; Call:	<none>
; Ret:	_CntX = number of left pages

get_left:
	 rcall	clr_page
glf_lp:	 rcall	next_block	; Block# ++
	lds	r16,SmPages	; If page# reaches end of medium, exit
	lds	r17,SmPages+1	; 
	cp	_PageM,r16	; 
	cpc	_PageH,r17	; 
	brcs	PC+3		; 
	sbi	PORTC,CE	; 
	ret			; /
	 rcall	chk_bad		; If bad block, exclude count
	breq	glf_lp		; /
	 rcall	sm_rd_page2	; If in-use, exclude count
	 rcall	sm_read		; 
	cpi	r16,0xff	; 
	brne	glf_lp		; /
	lds	r16,SmPPB	; Increment page counter
	inc	r16		; 
	add	_CntL,r16	; 
	adc	_CntM,_0	; 
	adc	_CntH,_0	; 
	rjmp	glf_lp		; /



;-----------------------------------------------;
; FS - Search next free page
;
; Call:  _PageX = Current Page#
; Ret:   C = 0:successfull, _PageX = next free page#
;        C = 1:no free block
;	 r17 = broken

sch_next:
	 rcall	next_page	; Page# ++;
	lds	r16,SmPPB	; If block didn't change, successful
	and	r16,_PageL	; 
	breq	PC+3		; 
	clc			; 
	ret			; /
				; When block is changed, serch next free block
	lds	r16,SmPages	;--- Block search loop
	lds	r17,SmPages+1	; If page# reaches end of medium, error
	cp	_PageM,r16	; 
	cpc	_PageH,r17	; 
	brcc	PC+9		; /
	 rcall	chk_bad		; If block is bad, next block
	breq	PC+5		; /
	 rcall	sm_rd_page2	; Read block status
	 rcall	sm_read		; /
	cpi	r16,0xff	; If not used, successful
	breq	PC+4		; /
	 rcall	next_block	; Block# ++;
	rjmp	PC-14		; continue search
	sec
	ret



;-----------------------------------------------;
; FS - Get current block number from page number
;
; Call: _PageX
; Ret:  r16:r17 = block number
; 	r18-r19 = broken

get_block:
	mov	r16,_PageL	; Get block number
	mov	r17,_PageM	;  r17:r16 = _PageX / block size
	mov	r18,_PageH	; 
	lds	r19,SmPPB	; 
	lsr	r18		; 
	ror	r17		; 
	ror	r16		; 
	lsr	r19		; 
	brne	PC-4		; /
	ret



;-----------------------------------------------;
; FS - Jump to next block or next page
;
; Call:  _PageX
; Ret:   _PageX = 1st page of next block, or next page
;	 r16 = broken

next_block:
	lds	r16,SmPPB
	or	_PageL,r16

next_page:	; Page ++
	inc	_PageL
	brne	PC+4
	inc	_PageM
	brne	PC+2
	inc	_PageH
	ret

clr_page:
	clr	_PageL		; Clear page#
	clr	_PageM		; 
	clr	_PageH		; /
	clr	_CntL		; Clear page counter
	clr	_CntM		; 
	clr	_CntH		; /
	ret



;-----------------------------------------------;
; FS - Synchronize BBT & TOC between RAM and SM
;

sync_fs:
	 rcall	clr_page	; Page = 0
	 rcall	sm_erase	; Erase 1st block
	 rcall	save_bbt	; Restore BBT
	rjmp	save_toc	; Restore TOC



;-----------------------------------------------;
; FS - Search and Display ID3 tag
;
; Call: r16 = Track#(0..
; Ret:  none

disp_id3:
	 rcall	get_trkpar	; Get track top and length
di_slp:				;--- Jump to page _CntX-2
	lds	r16,SmPPB	;  if _CntX < SmPPB+4
	addi	r16,4		;   r17 = 1;
	cp	_CntL,r16	;  else 
	cpc	_CntM,_0	;   r17 = SmPPB+1; _PageX = end page of block;
	cpc	_CntH,_0	;  endif
	ldi	r17,1		;  
	brcs	PC+5		;  
	lds	r17,SmPPB	;  
	or	_PageL,r17	;  
	inc	r17		;  /
	ldi	r16,3		;  if _CntX < 3
	cp	_CntL,r16	;   exit loop
	cpc	_CntM,_0	;   
	cpc	_CntH,_0	;   
	brcs	di_sle		;  /
	sub	_CntL,r17	;  _CntX -= r17;
	sbc	_CntM,_0	;  
	sbc	_CntH,_0	;  /
	 rcall	sm_rd_page2	;  Get following page #
	 rcall	sm_read		;  
	mov	_PageL,r16	;  
	 rcall	sm_read		;  
	mov	_PageM,r16	;  
	 rcall	sm_read		;  
	mov	_PageH,r16	;  /
	rjmp	di_slp		; /
di_sle:
	 rcall	sm_rd_page	; Search tag sign "TAG".
	clr	_LoopL		; 
	clr	_LoopH		; 
	cpi	_LoopH,high(1024);
	breq	exit_id3	; 
	mov	r18,r17		; 
	mov	r17,r16		; 
	 rcall	read_d3		; 
	cpi	r18,'T'		; 
	brne	PC-6		; 
	cpi	r17,'A'		; 
	brne	PC-8		; 
	cpi	r16,'G'		; 
	brne	PC-10		; /

	ldi	r17,30+22	; Display ID3 tag (Title(30), Artist(22))
	 rcall	read_d3		; 
	 rcall	xmit		; 
	dec	r17		; 
	brne	PC-3		; /
exit_id3:
	ret


read_d3:
	 rcall	sm_read		; Read a data
	subi	_LoopL,low(-1)	; Byte count ++
	sbci	_LoopH,high(-1)	; /
	mov	r1,r16
	mov	r16,_LoopH	; If page boundaly,
	andi	r16,0b00000001	;  link next page
	or	r16,_LoopL	; 
	brne	PC+8		; 
	 rcall	sm_read		; 
	mov	_PageL,r16	; 
	 rcall	sm_read		; 
	mov	_PageM,r16	; 
	 rcall	sm_read		; 
	mov	_PageH,r16	; 
	 rcall	sm_rd_page	; /
	mov	r16,r1
	ret


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -