📄 mpc_fs.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 + -