Advertisement
Guest User

Untitled

a guest
Sep 25th, 2017
191
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.02 KB | None | 0 0
  1. .include "drivecpu.i"
  2.  
  3. .export fat_cdroot, fat_cd, fat_dir_first, fat_dir_next
  4. .export fat_next_clust, fat_read_clust, fat_read_ptable
  5. .export cluster
  6. .exportzp fs_fat12
  7. .exportzp fs_fat16
  8. .exportzp fs_fat32
  9.  
  10. .importzp dirptr
  11. .importzp nameptr
  12. .importzp ptr
  13. .importzp sectorptr
  14.  
  15. .import dev_read_sector
  16. .import comparedirname
  17.  
  18. .import clusterbuf
  19.  
  20. .import lba
  21.  
  22. .import part_fstype
  23. .import part_secperclus
  24.  
  25. .import debug_puts
  26. .import debug_puthex
  27. .import dstr_crlf
  28. .import dstr_dircluster
  29. .import dstr_foundfat16
  30. .import dstr_foundfat32
  31.  
  32.  
  33. fs_fat12 = $12
  34. fs_fat16 = $16
  35. fs_fat32 = $32
  36. ptable = sectorbuf + 446
  37.  
  38.  
  39. .bss
  40.  
  41. part_fat: .res 4 ; 32-bit start of fat
  42. part_cstart: .res 4 ; 32-bit start of clusters
  43. part_num: .res 1 ; partition number
  44. part_start: .res 4 ; 32-bit LBA start address of active partition
  45. part_rootdir: .res 4 ; 32-bit root directory address
  46. scount: .res 1 ; number of sectors to read
  47. cluster: .res 4 ; 32-bit cluster address
  48. ; multiply by number of sectors per cluster
  49. ; add start of clusters
  50. ; and you get the logical block address
  51. sectorbuf: .res 512
  52.  
  53.  
  54. .code
  55.  
  56. ; load the root directory
  57. fat_cdroot:
  58. lda part_fstype
  59. cmp #fs_fat16
  60. beq @fat16
  61.  
  62. lda part_rootdir
  63. sta cluster
  64. lda part_rootdir+1
  65. sta cluster+1
  66. lda part_rootdir+2
  67. sta cluster+2
  68. lda part_rootdir+3
  69. sta cluster+3
  70.  
  71. @done:
  72. clc
  73. rts
  74.  
  75. @fat16:
  76. lda #0
  77. sta cluster
  78. sta cluster+1
  79. sta cluster+2
  80. sta cluster+3
  81. beq @done
  82.  
  83.  
  84. ; change directory
  85. ; needs the first cluster of the current dir in cluster
  86. ; and the name of the dir to change to in nameptr
  87. ; returns the new dir address in cluster or carry set on error
  88. fat_cd:
  89. jsr fat_dir_first
  90. bcs @error
  91.  
  92. @checkname:
  93. ldy #0
  94.  
  95. lda (dirptr),y
  96. beq @error ; if it's 0 we reached the end of the dir
  97. cmp #$e5 ; if it's $e5 it's a deleted file
  98. beq @next
  99.  
  100. ldy #11 ; check attrib flags
  101. lda (dirptr),y
  102. and #$10 ; bit 4 is the dir flag
  103. beq @next
  104.  
  105. dey ; compare name
  106. jsr comparedirname
  107. beq @founddir
  108.  
  109. @next:
  110. jsr fat_dir_next ; grab the next entry
  111. bcc @checkname
  112.  
  113. @error:
  114. sec
  115. rts
  116.  
  117. @founddir:
  118. ldy #$1a ; we found the directory, new cluster
  119. lda (dirptr),y ; address
  120. sta cluster
  121. iny
  122. lda (dirptr),y
  123. sta cluster+1
  124.  
  125. lda part_fstype
  126. cmp #fs_fat32
  127. bne @fat16
  128.  
  129. ldy #$14
  130. lda (dirptr),y
  131. sta cluster+2
  132. iny
  133. lda (dirptr),y
  134. sta cluster+3
  135. clc
  136. rts
  137.  
  138. @fat16:
  139. cmp #fs_fat16
  140. bne @error
  141.  
  142. lda #0
  143. sta cluster+2
  144. sta cluster+3
  145. clc
  146. rts
  147.  
  148.  
  149. ; find the first dir entry
  150. fat_dir_first:
  151. ;dputs dstr_dircluster
  152. ;dputnum32 cluster
  153. ;dputs dstr_crlf
  154.  
  155. jsr fat_read_clust ; load dir cluster into buffer
  156. bcc fat_dir_ok
  157.  
  158. fat_dir_error:
  159. sec
  160. rts
  161.  
  162. fat_dir_ok:
  163. lda #<clusterbuf ; point to beginning of dir
  164. sta dirptr
  165. lda #>clusterbuf
  166. sta dirptr+1
  167.  
  168. fat_dir_return:
  169. clc
  170. rts
  171.  
  172.  
  173. fat_dir_next:
  174. lda dirptr ; advance pointer 32 bytes to the
  175. clc ; next entry
  176. adc #32
  177. sta dirptr
  178. bcc @skip
  179. inc dirptr+1
  180. @skip:
  181. lda part_secperclus ; check if we've parsed the whole
  182. asl ; cluster
  183. ;clc
  184. adc #>clusterbuf
  185. cmp dirptr+1
  186. bne fat_dir_return
  187.  
  188. jsr fat_next_clust ; next cluster in chain
  189. beq fat_dir_error ; premature end of directory
  190. bcs fat_dir_error
  191. jsr fat_read_clust ; load cluster into buffer
  192. bcc fat_dir_ok
  193. bcs fat_dir_error
  194.  
  195.  
  196. next_dir_entry:
  197. @return:
  198. rts
  199.  
  200.  
  201. ; find the next linked cluster from the FAT
  202. fat_next_clust:
  203. lda part_fstype ; check for FAT16/FAT32
  204. cmp #fs_fat32
  205. beq f32_next_clust
  206. cmp #fs_fat16
  207. beq f16_next_clust
  208.  
  209. sec ; then what is it?
  210. rts
  211.  
  212. f16_next_clust:
  213. lda cluster+1 ; there are 2 bytes for each entry
  214. sta lba ; in the FAT this gives us 256
  215. lda cluster+2 ; entries in every FAT sector so
  216. sta lba+1 ; bits 31..8 of the current cluster
  217. lda cluster+3 ; address gives us the sector to
  218. sta lba+2 ; read
  219. lda #0
  220. sta lba+3
  221.  
  222. jsr addfatstart ; fat += part-fat
  223.  
  224. lda #<sectorbuf
  225. sta sectorptr
  226. lda #>sectorbuf
  227. sta sectorptr+1
  228.  
  229. jsr dev_read_sector
  230. bcs @error
  231.  
  232. lda cluster ; offset = cluster<<1
  233. asl
  234. tax
  235. bcs @upperhalf
  236.  
  237. lda sectorbuf,x ; copy new cluster address
  238. sta cluster
  239. inx
  240. lda sectorbuf,x
  241. sta cluster+1
  242.  
  243. jmp @checkeoc
  244.  
  245. @upperhalf:
  246. lda sectorbuf + 256,x
  247. sta cluster
  248. inx
  249. lda sectorbuf + 256,x
  250. sta cluster+1
  251.  
  252. @checkeoc:
  253. lda #0 ; this is FAT*16*
  254. sta cluster+2
  255. sta cluster+3
  256.  
  257. lda cluster+1 ; check for end of cluster chain
  258. cmp #$ff
  259. bne @done
  260.  
  261. lda cluster
  262. and #$f0 ; the 3 least significant bits are ignored
  263. cmp #$f0
  264.  
  265. @done:
  266. clc
  267. rts
  268.  
  269. @error:
  270. sec
  271. rts
  272.  
  273.  
  274. f32_next_clust:
  275. lda cluster+1 ; there are 4 bytes for each entry
  276. sta lba ; in the FAT this gives us 128 entries
  277. lda cluster+2 ; in every FAT sector so bits 31..7 of
  278. sta lba+1 ; the current cluster address gives us
  279. lda cluster+3 ; the FAT sector to read
  280. sta lba+2
  281. lda #0
  282. sta lba+3
  283.  
  284. lda cluster ; lba = cluster>>7
  285. asl
  286. rol lba
  287. rol lba+1
  288. rol lba+2
  289. rol lba+3
  290.  
  291. jsr addfatstart ; fat += part_fat
  292.  
  293. lda #<sectorbuf
  294. sta sectorptr
  295. lda #>sectorbuf
  296. sta sectorptr+1
  297.  
  298. jsr dev_read_sector
  299. bcs @error
  300.  
  301. lda cluster ; offset = (cluster & 127)<<2
  302. asl
  303. asl
  304. tax
  305. bcs @upperhalf
  306.  
  307. lda sectorbuf,x ; copy new cluster address
  308. sta cluster
  309. inx
  310. lda sectorbuf,x
  311. sta cluster+1
  312. inx
  313. lda sectorbuf,x
  314. sta cluster+2
  315. inx
  316. lda sectorbuf,x
  317. sta cluster+3
  318.  
  319. jmp @checkeoc
  320.  
  321. @upperhalf:
  322. lda sectorbuf + 256,x
  323. sta cluster
  324. inx
  325. lda sectorbuf + 256,x
  326. sta cluster+1
  327. inx
  328. lda sectorbuf + 256,x
  329. sta cluster+2
  330. inx
  331. lda sectorbuf + 256,x
  332. sta cluster+3
  333.  
  334. @checkeoc:
  335. lda cluster+1 ; check for end of cluster chain
  336. and cluster+2
  337. and cluster+3
  338. cmp #$ff
  339. bne @done
  340.  
  341. lda cluster
  342. and #$f8 ; the 3 least significant bits are ignored
  343. cmp #$f8
  344.  
  345. @done:
  346. clc
  347. rts
  348.  
  349. @error:
  350. sec
  351. rts
  352.  
  353.  
  354. ; lba += start of fat
  355. addfatstart:
  356. clc
  357. lda lba
  358. adc part_fat
  359. sta lba
  360. lda lba+1
  361. adc part_fat+1
  362. sta lba+1
  363. lda lba+2
  364. adc part_fat+2
  365. sta lba+2
  366. lda lba+3
  367. adc part_fat+3
  368. sta lba+3
  369. rts
  370.  
  371.  
  372. ; load the specified cluster to memory
  373. ; with ugly, ugly special case for FAT16 root directory
  374. .bss
  375. rctemp: .res 1 ; ugly, ugly fat16
  376. .code
  377.  
  378. fat_read_clust:
  379. lda cluster ; lba = cluster * secperclus + part_cstart
  380. sta lba
  381. sta rctemp
  382. lda cluster+1
  383. sta lba+1
  384. ora rctemp
  385. sta rctemp
  386. lda cluster+2
  387. sta lba+2
  388. ora rctemp
  389. sta rctemp
  390. lda cluster+3
  391. sta lba+3
  392. ora rctemp
  393. bne @notclusterzero
  394.  
  395. lda part_fstype
  396. cmp #fs_fat16
  397. bne @notclusterzero
  398.  
  399. lda part_rootdir
  400. sta lba
  401. lda part_rootdir+1
  402. sta lba+1
  403. lda part_rootdir+2
  404. sta lba+2
  405. lda part_rootdir+3
  406. sta lba+3
  407.  
  408. lda #16 ; assuming 512 rootdir entries for FAT16. ugly, ugly
  409. jmp @readsectors
  410.  
  411. @notclusterzero:
  412. lda part_secperclus ; multiply cluster address by number of
  413. @shift:
  414. lsr ; sectors per cluster. this number is a
  415. bcs @shifted ; power of two so we'll just shift.
  416. asl lba
  417. rol lba+1
  418. rol lba+2
  419. rol lba+3
  420. jmp @shift
  421. @shifted:
  422.  
  423. clc ; add start of clusters
  424. lda lba
  425. adc part_cstart
  426. sta lba
  427. lda lba+1
  428. adc part_cstart+1
  429. sta lba+1
  430. lda lba+2
  431. adc part_cstart+2
  432. sta lba+2
  433. lda lba+3
  434. adc part_cstart+3
  435. ;sta lba+3
  436.  
  437. ; we should now have the correct cluster in the lba address
  438.  
  439. lda part_secperclus ; number of sectors to read
  440. @readsectors:
  441. sta scount
  442.  
  443. lda #<clusterbuf ; load to cluster buffer
  444. sta sectorptr
  445. lda #>clusterbuf
  446. sta sectorptr+1
  447.  
  448. @readnext:
  449. jsr dev_read_sector
  450. bcs @error
  451.  
  452. inc lba ; next sector
  453. bne @done
  454. inc lba+1
  455. bne @done
  456. inc lba+2
  457. bne @done
  458. inc lba+3
  459. @done:
  460. dec scount
  461. bne @readnext
  462.  
  463. clc
  464. rts
  465.  
  466. @error:
  467. sec
  468. rts
  469.  
  470.  
  471. ; reads the partition table and finds the first FAT32 partition
  472. fat_read_ptable:
  473. lda #0 ; we'll find the partition
  474. sta lba ; table in sector 0
  475. sta lba+1
  476. sta lba+2
  477. sta lba+3
  478.  
  479. lda #<sectorbuf
  480. sta sectorptr
  481. lda #>sectorbuf
  482. sta sectorptr+1
  483.  
  484. jsr dev_read_sector
  485. bcs @error
  486.  
  487. jsr check_signature
  488. bcs @error
  489.  
  490. lda #<ptable ; pointer to the partition table
  491. sta ptr
  492. lda #>ptable
  493. sta ptr+1
  494. ldx #0
  495.  
  496. ldy #4
  497. @checktype:
  498. lda (ptr),y ; check file system type
  499. cmp #$04 ; fat16 uses $04, $06, or $0e
  500. beq foundfat16
  501. cmp #$06
  502. beq foundfat16
  503. cmp #$0e
  504. beq foundfat16
  505. cmp #$0b ; fat32 uses $0b or $0c
  506. beq _foundfat32
  507. cmp #$0c
  508. beq _foundfat32
  509.  
  510. lda ptr
  511. clc
  512. adc #16
  513. sta ptr
  514.  
  515. inx
  516. cpx #4
  517. bne @checktype
  518.  
  519. @error:
  520. sec
  521. rts
  522.  
  523. _foundfat32:
  524. jmp foundfat32 ; branch range. bah.
  525.  
  526.  
  527. foundfat16:
  528. inx
  529. stx part_num ; save partition number
  530.  
  531. dputs dstr_foundfat16
  532. txa
  533. dputnum
  534. dputs dstr_crlf
  535.  
  536. lda #fs_fat16 ; store partition type
  537. sta part_fstype
  538.  
  539. jsr loadvolid
  540. bcc @noerror
  541.  
  542. @error:
  543. sec
  544. rts
  545. @noerror:
  546. jsr checkgeom
  547. bne @error
  548.  
  549. jsr findfatstart
  550.  
  551. asl sectorbuf + $16 ; multiply fatsize by two
  552. rol sectorbuf + $17 ; possible overflow?
  553. bcs @error
  554.  
  555. ;clc
  556. lda part_fat ; skip fats to find rootdir *sector*
  557. adc sectorbuf + $16
  558. sta part_rootdir
  559. lda part_fat + 1
  560. adc sectorbuf + $17
  561. sta part_rootdir + 1
  562. lda part_fat + 2
  563. adc #0
  564. sta part_rootdir + 2
  565. lda part_fat + 3
  566. adc #0
  567. sta part_rootdir + 3
  568.  
  569. ldx #4 ; divide rootdirentries by 16 to
  570. @div16:
  571. lsr sectorbuf + $12 ; get the number of blocks
  572. ror sectorbuf + $11
  573. dex
  574. bne @div16
  575. bcs @error
  576.  
  577. ;clc
  578. lda part_rootdir ; skip rootdir to find start of
  579. adc sectorbuf + $11 ; clusters
  580. sta part_cstart
  581. lda part_rootdir + 1
  582. adc sectorbuf + $12
  583. sta part_cstart + 1
  584. lda part_rootdir + 2
  585. adc #0
  586. sta part_cstart + 2
  587. lda part_rootdir + 3
  588. adc #0
  589. sta part_cstart + 3
  590.  
  591. jmp subcluster
  592.  
  593.  
  594. foundfat32:
  595. inx
  596. stx part_num ; save partition number
  597.  
  598. dputs dstr_foundfat32
  599. txa
  600. dputnum
  601. dputs dstr_crlf
  602.  
  603. lda #fs_fat32 ; store partition type
  604. sta part_fstype
  605.  
  606. jsr loadvolid
  607. bcc @noerror
  608.  
  609. @error:
  610. sec
  611. rts
  612. @noerror:
  613. jsr checkgeom
  614. bne @error
  615.  
  616. jsr findfatstart
  617.  
  618. lda sectorbuf + $2c ; store address of root directory
  619. sta part_rootdir
  620. lda sectorbuf + $2d
  621. sta part_rootdir+1
  622. lda sectorbuf + $2e
  623. sta part_rootdir+2
  624. lda sectorbuf + $2f
  625. sta part_rootdir+3
  626.  
  627. ; find start of clusters
  628.  
  629. asl sectorbuf + $24 ; multiply FAT size by two
  630. rol sectorbuf + $25
  631. rol sectorbuf + $26
  632. rol sectorbuf + $27
  633.  
  634. clc ; then skip them
  635. lda part_fat
  636. adc sectorbuf + $24
  637. sta part_cstart
  638. lda part_fat+1
  639. adc sectorbuf + $25
  640. sta part_cstart+1
  641. lda part_fat+2
  642. adc sectorbuf + $26
  643. sta part_cstart+2
  644. lda part_fat+3
  645. adc sectorbuf + $27
  646. sta part_cstart+3
  647.  
  648. subcluster:
  649. ldx #2 ; subtract two clusters to compensate
  650. @subcluster:
  651. sec ; for reserved values 0 and 1
  652. lda part_cstart
  653. sbc part_secperclus
  654. sta part_cstart
  655. lda part_cstart+1
  656. sbc #0
  657. sta part_cstart+1
  658. lda part_cstart+2
  659. sbc #0
  660. sta part_cstart+2
  661. lda part_cstart+3
  662. sbc #0
  663. sta part_cstart+3
  664. dex
  665. bne @subcluster
  666.  
  667. ; ok, we have now initialized everything we need
  668. ; to load files from the partition
  669.  
  670. clc
  671. rts
  672.  
  673.  
  674. loadvolid:
  675. ldy #8 ; grab the address of the volume ID
  676. lda (ptr),y
  677. sta lba
  678. sta part_start
  679. iny
  680. lda (ptr),y
  681. sta lba+1
  682. sta part_start+1
  683. iny
  684. lda (ptr),y
  685. sta lba+2
  686. sta part_start+2
  687. iny
  688. lda (ptr),y
  689. sta lba+3
  690. sta part_start+3
  691.  
  692. lda #<sectorbuf
  693. sta sectorptr
  694. lda #>sectorbuf
  695. sta sectorptr+1
  696.  
  697. jsr dev_read_sector
  698. bcs @error
  699.  
  700. jsr check_signature ; check for $aa55
  701. bcs @error
  702.  
  703. clc
  704. @error:
  705. rts
  706.  
  707.  
  708. findfatstart:
  709. clc ; first skip reserved sectors
  710. lda lba
  711. adc sectorbuf + $0e
  712. sta part_fat
  713. lda lba+1
  714. adc sectorbuf + $0f
  715. sta part_fat+1
  716. lda lba+2
  717. adc #0
  718. sta part_fat+2
  719. lda lba+3
  720. adc #0
  721. sta part_fat+3
  722. rts
  723.  
  724.  
  725. checkgeom:
  726. lda sectorbuf + $0b ; make sure sector size is 512
  727. bne @checkfail
  728. lda sectorbuf + $0c
  729. cmp #2
  730. bne @checkfail
  731.  
  732. lda sectorbuf + $10 ; make sure there are 2 FATs
  733. cmp #2
  734. bne @checkfail
  735.  
  736. lda sectorbuf + $0d ; number of sectors per cluster
  737. sta part_secperclus
  738. and #$80 ; we can't handle 64K clusters
  739. @checkfail:
  740. rts
  741.  
  742.  
  743. ; check for signature bytes
  744. check_signature:
  745. lda sectorbuf + $1fe
  746. cmp #$55
  747. bne @error
  748.  
  749. lda sectorbuf + $1ff
  750. cmp #$aa
  751. bne @error
  752.  
  753. clc
  754. rts
  755. @error:
  756. sec
  757. rts
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement