]> cloudbase.mooo.com Git - avrcpm.git/blob - avr/dsk_fat16.asm
* I2C: Don't get stuck, if pullups are missing (timeout error)
[avrcpm.git] / avr / dsk_fat16.asm
1 ; Various functions for the Interaction with the FAT16 Filesystem
2 ;
3 ; Copyright (C) 2010 Frank Zoll
4 ; Copyright (C) 2010 Sprite_tm
5 ; Copyright (C) 2010 Leo C.
6 ;
7 ; This file is part of avrcpm.
8 ;
9 ; avrcpm is free software: you can redistribute it and/or modify it
10 ; under the terms of the GNU General Public License as published by
11 ; the Free Software Foundation, either version 3 of the License, or
12 ; (at your option) any later version.
13 ;
14 ; avrcpm is distributed in the hope that it will be useful,
15 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ; GNU General Public License for more details.
18 ;
19 ; You should have received a copy of the GNU General Public License
20 ; along with avrcpm. If not, see <http://www.gnu.org/licenses/>.
21 ;
22 ; $Id$
23 ;
24
25 ; ============================================================================
26 ; Prelimitary !
27 ; °°°°°°°°°°°°°
28 ; Size of a Sector is fixed to 512 Bytes by Base - MMC Driver implementation
29 ; The Functions below therefore assume a fixed Size of 512 Bytes per Sector.
30 ; ============================================================================
31
32 #if FAT16_SUPPORT
33
34
35 ; ############################################################################
36 ; Defines for FAT16 Structures
37 ; ############################################################################
38
39 /*These are the Offsets to the Variables within the Bootsector of a FAT16
40 Partition.
41 */
42 ;#define FAT16_BSO_SECSIZE 0x0b ; Offset to Sectorsize Word
43 #define FAT16_BSO_CLUSTSZ 0x0d ; Offset to Clustersize Byte
44 #define FAT16_BSO_RESSECT 0x0e ; Offset to Number of Reserved Sectors
45 #define FAT16_BSO_VOLPTR 0x1c ; Offset to First VolumeSector
46 #define FAT16_BSO_SECPERFAT 0x16 ; Offset to Number of Sectors per Fat
47 #define FAT16_BSO_NUMFATCP 0x10 ; Offset to Ammount of FAT Copys
48 #define FAT16_BSO_NUMDIRENT 0x11 ; Offset to Max. Root Dir. Entrys
49 #define FAT16_FIRST_IMAGENAME 'A' ; First letter of filename to search
50 #define FAT16_LAST_IMAGENAME 'Z' ; Last letter of filename to
51 /*
52 #define FAT16_LAST_IMAGENAME 'A'+MAXDISKS-1 ; Last letter of filename to
53 ; search
54 */
55
56 ; ############################################################################
57 ; Start of Data Segment
58 ; ############################################################################
59 .dseg
60
61 fat_partfound: .byte 1 ; (partition: 0= no found 1=found )
62 fat_parttbl: .byte 4 ; first fat16 partition entry
63 ; only startsector is needed
64 fat_clustersize: .byte 1 ; sectors per cluster
65 fat_numdirentrys:.byte 2 ; Max. num. of entrys within Rootdirektory
66 fat_ptr2fat: .byte 4 ; pointer to the first fat sector
67 fat_ptr2dat: .byte 4 ; pointer to the first data sector
68
69 /*These variables define a cache that holds the last Cluster and Sector
70 thats been searched vor. To save some of the valuabe SRAM- Space these
71 variables also are used as temporary variables by the function
72 fat_scan_partition.
73 */
74 fat_last_dsk: .byte 1 ; number of disk with entry in cache
75 fat_log_clust: .byte 2 ; last searched logical cluster
76 fat_clust_offset: .byte 1 ; offset within the cluster
77 fat_clust_ptr: .byte 4 ; sector of last real cluster
78
79 /* This Variable is only needed within the scanning of the directory
80 for tempoary variable storage.. todo: optimize away :-) */
81 fat_temp: .byte 3 ; for tempoary use
82
83 ; ############################################################################
84 ; Start of Code Segment
85 ; ############################################################################
86 .cseg
87
88 ; ============================================================================
89 ; Function: Initialize internal FAT-Partition Variables
90 ; ============================================================================
91 ; Parameters
92 ; ----------------------------------------------------------------------------
93 ; Registers : none
94 ; Variables : [out] fat_parttabl
95 ; ----------------------------------------------------------------------------
96 ; Description:
97 ; This Routine initializes the internal Variables, that point to the
98 ; first Found FAT16 Partition.
99 ; ============================================================================
100 fat_init_partitiontable:
101
102 sts fat_partfound,_0
103
104 ldiw y,fat_parttbl
105 st y+,_0
106 st y+,_0
107 st y+,_0
108 st y+,_0
109 ret
110
111 ; ============================================================================
112 ; Function: Resets the Cache
113 ; ============================================================================
114 ; Parameters
115 ; ----------------------------------------------------------------------------
116 ; Registers : none
117 ; Variables : [out] fat_log_clust
118 ; [out] fat_last_dsk
119 ; ----------------------------------------------------------------------------
120 ; Description:
121 ; This Routine resets the internal Cache- Variables. After reset, the
122 ; next read or write Command will initialize a scan of the FAT of
123 ; the FAT16-Partition for the given sector.
124 ; ============================================================================
125 fat_reset_cache:
126 push yl
127 ldi yl,0xFF
128 sts fat_log_clust ,yl
129 sts fat_log_clust+1,yl
130 sts fat_last_dsk ,yl
131 pop yl
132 ret
133
134 ; ============================================================================
135 ; Function: Saves FAT16 Partitiondata for later Scanning
136 ; ============================================================================
137 ; Parameters
138 ; ----------------------------------------------------------------------------
139 ; Registers : [in] z Pointer to the Partitondata
140 ; Variables : [out] fat_partfound Boolean for "Partition found"
141 ; [out] fat_parttbl Pointer to Partitiontable
142 ; ----------------------------------------------------------------------------
143 ; Description:
144 ; This funktion sets the internal Variables to the Start and Size
145 ; of a given FAT16 Paritition. This Information will be used for a
146 ; later scanning of the Partition. See Function "fat_scan_partition"
147 ; for more information.
148 ; ============================================================================
149 fat_add_partition:
150
151 .if FAT16_DEBUG > 0
152 printstring "fat16 part found"
153 printnewline
154 .endif
155
156
157 ; save variables on stack
158 push yl
159 push yh
160
161 ; set fat16 partition found flag
162 ldi yl,1
163 sts fat_partfound,yl
164
165 ; save data from first fat16 partition
166 ldiw y,fat_parttbl
167
168 ldd temp,z+PART_START
169 st y+,temp
170 ldd temp,z+PART_START+1
171 st y+,temp
172 ldd temp,z+PART_START+2
173 st y+,temp
174 ldd temp,z+PART_START+3
175 st y+,temp
176
177 ; reload variables from stack
178 pop yh
179 pop yl
180
181 ret
182
183 ; ============================================================================
184 ; Read and Scann a FAT16 Partition for Imagedatefiles
185 ; ============================================================================
186 ; Registers : none
187 ; Variables : none
188 ; ----------------------------------------------------------------------------
189 ; This Routine reads the Bootblock and scanns it for a Diskimage
190 ; ============================================================================
191
192
193 fat_scan_partition:
194
195 .if FAT16_DEBUG > 0
196 printstring "fat16 scanning"
197 printnewline
198 .endif
199
200 ; Check if a FAT16 Partition was realy found
201 lds yl,fat_partfound
202 cpi yl,1
203 brne fat_scan_error
204
205
206 .if FAT16_DEBUG > 0
207 printstring "free entrys in ptable ?"
208 printnewline
209 .endif
210
211 ; Check for free Entrys in Partition table
212 lds yl,ndisks
213 cpi yl,MAXDISKS
214 breq fat_scan_error
215
216 .if FAT16_DEBUG > 0
217 printstring "read fat bootblock."
218 printnewline
219 .endif
220
221 ; Scan partition start
222 ldiw z,fat_parttbl
223 ldd xl,z+0
224 ldd xh,z+1
225 ldd yl,z+2
226 ldd yh,z+3
227
228 ; Load first sector from Partition
229 rcall mmcReadSect
230 tst temp
231 breq fat_bootblock_check
232
233 ; Read error: Block not found
234 fat_scan_error:
235 clr temp
236 ret
237
238 fat_bootblock_check:
239
240 .if FAT16_DEBUG > 0
241 printstring "fat16 bootblock check"
242 printnewline
243 .endif
244
245 ; get sectors per cluster from bootblock
246 ldiw z,hostbuf+FAT16_BSO_CLUSTSZ
247 ld temp,z
248 sts fat_clustersize,temp
249
250 .if FAT16_DEBUG > 0
251 printstring "Sectors per Cluster "
252 rcall printhex
253 printnewline
254 .endif
255
256 ; get num of FAT Tables from bootblock
257 ldiw z,hostbuf+FAT16_BSO_NUMFATCP
258 ld temp,z
259 sts fat_last_dsk,temp ; low byte
260
261 .if FAT16_DEBUG > 0
262 printstring "Ammount of FAT copies: "
263 rcall printhex
264 printnewline
265 .endif
266
267 ; get max num of entrys in root direktory from bootblock
268 ldiw z,hostbuf+FAT16_BSO_NUMDIRENT
269 ld temp,z+
270 sts fat_numdirentrys,temp ; low byte
271 ld temp2,z
272 sts fat_numdirentrys+1,temp2 ; high byte
273
274 .if FAT16_DEBUG > 0
275 printstring "Max. entrys in Rootdir.: "
276 rcall printhexw
277 printnewline
278 .endif
279
280 ; Print begin of Volume
281 .if FAT16_DEBUG > 1
282
283 ldiw z,fat_parttbl
284 ldd xl,z+0
285 ldd xh,z+1
286 ldd yl,z+2
287 ldd yh,z+3
288
289 printstring "Begin of Volume at: "
290 mov temp ,yl
291 mov temp2,yh
292 rcall printhexw
293 mov temp ,xl
294 mov temp2,xh
295 rcall printhexw
296 printnewline
297 .endif
298
299 ; get num of sectors per FAT-Table from bootblock
300 ldiw z,hostbuf+FAT16_BSO_SECPERFAT
301 ld temp,z+
302 sts fat_log_clust,temp ; low byte
303 ld temp2,z
304 sts fat_log_clust+1,temp2 ; high byte
305
306 .if FAT16_DEBUG > 0
307 printstring "Sectors per FAT__: "
308 rcall printhexw
309 printnewline
310 .endif
311
312 ; get num of reseved sectors from bootblock
313 ldiw z,hostbuf+FAT16_BSO_RESSECT
314 ld temp,z+
315 ld temp2,z
316
317 ; Calculate begin of FAT within the Volume
318 ldiw z,fat_parttbl
319 ldd xl,z+0
320 ldd xh,z+1
321 ldd yl,z+2
322 ldd yh,z+3
323
324 add xl,temp
325 adc xh,temp2
326 adc yl,_0
327 adc yh,_0
328
329 sts fat_ptr2fat ,xl
330 sts fat_ptr2fat+1,xh
331 sts fat_ptr2fat+2,yl
332 sts fat_ptr2fat+3,yh
333
334 .if FAT16_DEBUG > 1
335 printstring "Begin of FAT at___: "
336 mov temp ,yl
337 mov temp2,yh
338 rcall printhexw
339 mov temp ,xl
340 mov temp2,xh
341 rcall printhexw
342 printnewline
343 .endif
344
345 ; Calculate begin of Root- Directory within the Volume
346 ldiw z,fat_ptr2fat
347 ldd xl,z+0
348 ldd xh,z+1
349 ldd yl,z+2
350 ldd yh,z+3
351
352 lds temp ,fat_log_clust
353 lds temp2,fat_log_clust+1
354 lds temp3,fat_last_dsk
355
356 fat_calc_dp_loop:
357 cp temp3,_0
358 breq fat_calc_dp_lend
359
360 add xl,temp
361 adc xh,temp2
362 adc yl,_0
363 adc yh,_0
364
365 dec temp3
366
367 rjmp fat_calc_dp_loop
368 fat_calc_dp_lend:
369
370 sts fat_clust_ptr ,xl
371 sts fat_clust_ptr+1,xh
372 sts fat_clust_ptr+2,yl
373 sts fat_clust_ptr+3,yh
374
375
376 .if FAT16_DEBUG > 1
377 printstring "Begin of DIR at___: "
378 mov temp ,yl
379 mov temp2,yh
380 rcall printhexw
381 mov temp ,xl
382 mov temp2,xh
383 rcall printhexw
384 printnewline
385 .endif
386
387 ; Calculate begin of DATA Clusters within the Volume
388 ; Num. Dir.Sektors = (Num. of Dir. Entrys * 32) / Bytes per Sektor
389
390 ; Sectorsize is fixed at 512 Bytes, makes 16 Entrys per Sektor
391
392 lds zl,fat_numdirentrys ; low byte
393 lds zh,fat_numdirentrys+1 ; high byte
394
395 ; Num. Direntrys / 16
396 lsr zh
397 ror zl
398 lsr zh
399 ror zl
400 lsr zh
401 ror zl
402 lsr zh
403 ror zl
404
405 lds xl,fat_clust_ptr
406 lds xh,fat_clust_ptr+1
407 lds yl,fat_clust_ptr+2
408 lds yh,fat_clust_ptr+3
409
410 add xl,zl
411 adc xh,zh
412 adc yl,_0
413 adc yh,_0
414
415 sts fat_ptr2dat ,xl
416 sts fat_ptr2dat+1,xh
417 sts fat_ptr2dat+2,yl
418 sts fat_ptr2dat+3,yh
419
420 .if FAT16_DEBUG > 1
421 printstring "Begin of Data at__: "
422 mov temp ,yl
423 mov temp2,yh
424 rcall printhexw
425 mov temp ,xl
426 mov temp2,xh
427 rcall printhexw
428 printnewline
429 .endif
430
431 ; Here Starts the Scann of the Directory for valid image Files.
432
433 ; Init Image-Namecounter
434 ldi temp,FAT16_FIRST_IMAGENAME
435 sts fat_last_dsk,temp
436
437 fat_scan_for_next_image:
438
439 ; Init Offset into Directory-Sectors
440 ldi temp,0
441 sts fat_clust_offset,temp
442
443 ; Init counter for number of entry left to scan
444 lds temp,fat_numdirentrys
445 sts fat_log_clust ,temp
446
447 lds temp,fat_numdirentrys+1
448 sts fat_log_clust+1,temp
449
450 fat_next_sector_loop:
451 ; Get a Pointer to the first Directory sector
452 lds xl,fat_clust_ptr
453 lds xh,fat_clust_ptr+1
454 lds yl,fat_clust_ptr+2
455 lds yh,fat_clust_ptr+3
456
457 ; Add actual offset
458 lds temp,fat_clust_offset
459 add xl,temp
460 adc xh,_0
461 adc yl,_0
462 adc yh,_0
463
464 ; Load sector from Directory
465 lcall mmcReadSect
466 tst temp
467 breq fat_look_for_images
468
469 ; Read error: Block not found
470 clr temp
471 ret
472
473 ; Looks at a read directory block for image entrys
474 fat_look_for_images:
475
476 ldiw z,hostbuf
477 ldi temp2,0
478
479 fat_look_for_loop:
480 ldd temp,z+0
481 cpi temp,'C'
482 brne fat_look_not_ok
483
484 ldd temp,z+1
485 cpi temp,'P'
486 brne fat_look_not_ok
487
488 ldd temp,z+2
489 cpi temp,'M'
490 brne fat_look_not_ok
491
492 ldd temp,z+3
493 cpi temp,'D'
494 brne fat_look_not_ok
495
496 ldd temp,z+4
497 cpi temp,'S'
498 brne fat_look_not_ok
499
500 ldd temp,z+5
501 cpi temp,'K'
502 brne fat_look_not_ok
503
504 ldd temp,z+6
505 cpi temp,'_'
506 brne fat_look_not_ok
507
508 lds temp3,fat_last_dsk ; Get actual Diskname (A to Z)
509 ldd temp,z+7
510 cp temp,temp3
511 brne fat_look_not_ok
512
513 ldd temp,z+8
514 cpi temp,'I'
515 brne fat_look_not_ok
516
517 ldd temp,z+9
518 cpi temp,'M'
519 brne fat_look_not_ok
520
521 ldd temp,z+10
522 cpi temp,'G'
523 brne fat_look_not_ok
524
525 sts fat_temp ,zl
526 sts fat_temp+1,zh
527 sts fat_temp+2,temp2
528 rjmp fat_store_new_entry
529
530 fat_scan_for_more:
531
532 lds zl ,fat_temp
533 lds zh ,fat_temp+1
534 lds temp2,fat_temp+2
535 fat_look_not_ok:
536
537 adiw z,32
538
539 inc temp2
540 cpi temp2,16 ; max entrys/sector
541 breq fat_scan_next_sector
542 rjmp fat_look_for_loop
543
544 fat_scan_next_sector:
545
546
547 lds temp3, fat_log_clust
548 lds temp4, fat_log_clust+1
549
550 sub temp3,temp2
551 sbc temp4,_0
552
553 sts fat_log_clust,temp3
554 sts fat_log_clust+1,temp4
555
556 cp temp3,_0
557 cpc temp4,_0
558 breq fat_scan_at_end
559
560 lds temp,fat_clust_offset
561 inc temp
562 sts fat_clust_offset,temp
563
564 rjmp fat_next_sector_loop
565
566 fat_scan_at_end:
567
568 lds temp,fat_last_dsk
569 inc temp
570 sts fat_last_dsk,temp
571
572 ldi temp2,FAT16_LAST_IMAGENAME
573 cp temp,temp2
574 brge fat_scaned_last_disk
575
576 rjmp fat_scan_for_next_image
577
578 fat_scaned_last_disk:
579
580 rjmp fat_scan_end
581
582
583 ; Create new Partition Entry
584 fat_store_new_entry:
585
586 ; Found a valid image
587 .if FAT16_DEBUG > 1
588 printstring "Found a valid Image! Z="
589 mov temp ,zl
590 mov temp2,zh
591 rcall printhexw
592 printnewline
593 .endif
594
595 ldiw y,hostparttbl
596 lds temp3,ndisks
597
598 fat_look_store_loop:
599 tst temp3
600 breq fat_look_store
601
602 adiw y,PARTENTRY_SIZE
603 dec temp3
604 rjmp fat_look_store_loop
605
606 fat_look_store:
607 ; Set Type of Partition to FAT16- Fileimage
608 ldi temp,dskType_FAT
609 std y+0,temp
610
611
612 ; Offset to Startcluster + 2
613 ldd temp,z+0x1A
614 std y+1,temp
615
616 ldd temp,z+0x1B
617 std y+2,temp
618
619 ldi temp,0
620 std y+3,temp
621 std y+4,temp
622
623 ; Convert Filesize to ammount of sectors
624 ; (calc with 512byte/sector)
625 ldd _tmp0,z+0x1C
626 ldd xl,z+0x1D
627 ldd xh,z+0x1E
628 ldd zl,z+0x1F
629 ; mov zh,_0
630
631 cpse _tmp0,_0 ;round up
632 adiw x,1
633 adc zl,_0
634
635 lsr zl
636 ror xh
637 ror xl
638
639 adc xl,_0
640 adc xh,_0
641 adc zl,_0
642
643 ; store ammount of sectors in partitiontable
644
645 tst zl ;file size larger than 65535 sectors?
646 breq fat_add_noprune
647
648 ldi xl,255
649 ldi xh,255
650 fat_add_noprune:
651 std y+5,xl
652 std y+6,xh
653
654 .if FAT16_DEBUG > 1
655 ; Test finding of the first sector
656
657 ldd xl,z+0x1A
658 ldd xh,z+0x1B
659
660 rcall fat_gethostsec
661
662 printstring "Begin of Image at: "
663 mov temp ,yl
664 mov temp2,yh
665 rcall printhexw
666 mov temp ,xl
667 mov temp2,xh
668 rcall printhexw
669 printnewline
670
671 .endif
672 ; Check for another free entry in partition table
673 lds temp,ndisks
674 inc temp
675 sts ndisks,temp
676
677 cpi temp,MAXDISKS
678 breq fat_scan_end
679
680 rjmp fat_scan_for_more
681
682 fat_scan_end:
683
684 ret
685
686
687 ; ============================================================================
688 ; Function: Cluster to HostSector
689 ; ============================================================================
690 ; Parameters: [in] xh,xl Cluster Number
691 ; [out] yh,yl,xh,xl Sector Number on Disk
692 ; ----------------------------------------------------------------------------
693 ; Registers :
694 ; Variables : [used] fat_clustersize Ammount of Sectors per Cluster
695 ; [changes] temp
696 ; ----------------------------------------------------------------------------
697 ; Description:
698 ; ! Only works with Clustersizes 2,4,8,16,32,64,128 !
699 ; ============================================================================
700 fat_gethostsec:
701
702 ; Get Offset into Data area of Disk
703 rcall fat_clusttosec
704
705
706 ; add begin of data area to offset
707 lds temp,fat_ptr2dat+0
708 add xl,temp
709 lds temp,fat_ptr2dat+1
710 adc xh,temp
711 lds temp,fat_ptr2dat+2
712 adc yl,temp
713 lds temp,fat_ptr2dat+3
714 adc yh,temp
715 ret
716
717 ; ============================================================================
718 ; Function: Cluster to Sector
719 ; ============================================================================
720 ; Registers: [in] xl,xh Cluster Number
721 ; [out] xl,xh,yl,yh Sector Number
722 ; Variables: [in] fat_clustersize Ammount of Sectors per Cluster
723 ; [out] temp =0
724 ; ----------------------------------------------------------------------------
725 ; Description:
726 ; Calculates the logical Sectornumber given the physical ClusterNumber
727 ; and the size of a Cluster un sectors.
728 ;
729 ; ! Only works with Clustersizes 2,4,8,16,32,64,128 !
730 ; ============================================================================
731 fat_clusttosec:
732 clr yl
733 clr yh
734
735 ldi temp,2
736 sub xl,temp ; Substract the 2 reserved clusters
737 sbc xh,_0
738
739 lds temp,fat_clustersize
740 lsr temp
741
742 fat_c2s_loop:
743 tst temp
744 breq fat_c2s_end
745 lsr temp
746
747 lsl xl
748 rol xh
749 rol yl
750 rol yh
751 rjmp fat_c2s_loop
752
753 fat_c2s_end:
754 ret
755
756 ; ====================================================================
757 ; Function: Searches a physical Cluster, given the logical Cluster
758 ; ====================================================================
759 ; Registers: [in] xh,xl logical- Cluster
760 ; [out] yh,yl physical- Cluster
761 ; Variables:
762 ; --------------------------------------------------------------------
763 ; Description:
764 ; ====================================================================
765 fat_find_phsy_clust:
766 lds zl,hostdsk
767 rcall dsk_getpartentry ; get partition entry
768
769 ; Get First FAT- Cluster Number of Diskimage
770
771 ldd yl,z+1
772 ldd yh,z+2
773
774 .if FAT16_DBG_FAT > 0
775 printstring "Search log. Cluster "
776 mov temp,xl
777 mov temp2,xh
778 lcall printhexw
779 printnewline
780
781 printstring "Search phys. Cluster "
782 mov temp ,yl
783 mov temp2,yh
784 lcall printhexw
785 printnewline
786 .endif
787
788 fat_next_phsy_clust:
789 cp xl,_0
790 cpc xh,_0
791 breq fat_found_phsy_clust
792 ; Get Next Cluster from Fat
793
794 ; Trick: 512 Bytes Per Sector equals to 256 FAT- Entrys per Sector
795 ; so given: yl is the Offset within the FAT Sector
796 ; yh is the number off se FAT sector to Read
797
798 ; in zh,zl: Pointer to Word within the Sector to read
799 ; in yh..xl: Start sector number (LBA)
800 ; out zh,zl : word thats been read
801 push xl
802 push xh
803
804 ; Create FAT Offset Value
805 clr zh
806 mov zl,yl
807 lsl zl
808 rol zh
809 ; Get FAT Start
810 mov temp,yh
811 lds xl,fat_ptr2fat
812 lds xh,fat_ptr2fat+1
813 lds yl,fat_ptr2fat+2
814 lds yh,fat_ptr2fat+3
815 ; Add Cluster offset within sector
816 add xl,temp
817 adc xh,_0
818 adc yl,_0
819 adc yh,_0
820 lcall mmcReadWord
821
822 pop xh
823 pop xl
824
825 mov yl,zl
826 mov yh,zh
827
828 ; Check next logical Cluster
829 ldi zl,1
830 sub xl,zl
831 sbc xh,_0
832 rjmp fat_next_phsy_clust
833
834 ; Found the physical cluster
835 fat_found_phsy_clust:
836
837 .if FAT16_DBG_FAT > 0
838 printstring "Found phys. Cluster at:"
839 mov temp,yl
840 mov temp2,yh
841 lcall printhexw
842 printnewline
843 .endif
844
845 ret
846
847 ; ============================================================================
848 ; Function: This Routine searches for the Sector within an Imagefile
849 ; ============================================================================
850 ; Registers: [out] xl,xh,yl,yh Pointer to the Sector on the SD-Card
851 ; [out] temp Error- Variable (0= No Error)
852 ; Variables: [in] hostdsk host disk #, (partition #)
853 ; [in] hostlba host block #, relative to part.start
854 ; [in] fat_last_dsk number of disk with entry in cache
855 ; [in] fat_log_clust last searched logical cluster
856 ; [in] fat_clust_offset offset within the cluster
857 ; [in] fat_clust_ptr sector of last real cluster
858 ; ----------------------------------------------------------------------------
859 ; Description:
860 ; This Routine uses the variables hostdsk and hostlba to find an Sector
861 ; in the Imagefile.
862 ; The CP/M Sector given within "hostlba" are splited to a logical Cluster-
863 ; Number and the Subsector within this logical Cluster.
864 ; logical Cluster Number = hostlba / fat_clustersize
865 ; The logical Cluster Number will be compared to the logical Cluster- Number
866 ; within the Cache. When this Clusters are the same and the DiskID's are
867 ; also the same, then the cached physical Sector will be used.
868 ; When the Clusters or the Disks don't match, a seek for the physical
869 ; Cluster is performed. This seek is done thru an access over the FAT of
870 ; the FAT16 Partition. The Routine starts at the first Cluster of the
871 ; Imagefile and goes along the linked list of Clusternumber till it reaches
872 ; the searched cluster. The found Clusternumber will be used to calculate
873 ; the Sektor where this Cluster lies on the SD- Card. Both the found physical
874 ; Cluster and the logical Cluster together with the physical Sectornumber
875 ; are stored in the cache.
876 ; The last step done is to add the SubSectorOffset to the found physical
877 ; Sector. This gives the pointer to the Sector to be read and or written.
878 ; ============================================================================
879
880 fat_hostparam:
881 lds zl,hostdsk
882 rcall dsk_getpartentry ; get partition entry
883
884 fat_hostlend:
885 lds temp ,hostlba
886 lds temp2,hostlba+1
887 ; lds temp3,hostlba+2
888
889
890 ldd xl,z+5 ; get size of disk in sectors
891 ldd xh,z+6
892 ; ldd yl,z+7
893
894 cp temp,xl ; check given sector against disksize
895 cpc temp2,xh
896 ; cpc temp3,yl
897 brcs fat_hp1
898
899 clr temp
900 ret
901
902 fat_hp1:
903 ; ################# Get logical Number of Cluster within the imagefile
904 ; printstring "calc log sector"
905 ; Get logical Sectornumber from temp
906 mov xl,temp
907 mov xh,temp2
908 ; mov yl,temp3
909 mov yl,_0
910 mov yh,_0
911 ; Divide logical Sectornumber by size of Cluster in sectors
912 lds zl,fat_clustersize
913 lsr zl
914 fat_search_clst_lp:
915 tst zl
916 breq fat_found_clst
917
918 lsr yh
919 ror yl
920 ror xh
921 ror xl
922
923 lsr zl
924
925 rjmp fat_search_clst_lp
926
927 fat_found_clst:
928 ; at this point xh and xl are carying the logical cluster number
929 ; printstring "find subsector"
930 ; ################# Get Subsector within the logical Cluster for later use
931 mov yl,xl
932 lds zl,fat_clustersize
933 lsr zl
934 fat_search_clst_lp2:
935 tst zl
936 breq fat_found_subsec
937 lsl yl
938
939 lsr zl
940 rjmp fat_search_clst_lp2
941
942 fat_found_subsec:
943 mov zl,temp
944 sub zl,yl
945 sts fat_clust_offset,zl
946
947 ; Check against last HOSTDISK searched
948 lds yl,fat_last_dsk
949 lds yh,hostdsk
950 cp yl,yh
951 brne fat_wrong_cache_clst
952
953 ; Check against last Cluster searched
954 lds yl,fat_log_clust
955 lds yh,fat_log_clust+1
956
957 cp yl,xl
958 brne fat_wrong_cache_clst
959 cp yh,xh
960 brne fat_wrong_cache_clst
961
962 ; Last Cluster = searched Cluster -> get Sectornumber from cache
963 lds xl,fat_clust_ptr
964 lds xh,fat_clust_ptr+1
965 lds yl,fat_clust_ptr+2
966 lds yh,fat_clust_ptr+3
967
968 rjmp fat_add_offset
969
970 ; Cluster is not in cache, so we must search for it
971 fat_wrong_cache_clst:
972 lds yl,hostdsk
973 sts fat_last_dsk,yl
974 sts fat_log_clust,xl
975 sts fat_log_clust+1,xh
976
977 ; Map Logical Cluster-Number to "Physical" Cluster Number using the FAT
978 rcall fat_find_phsy_clust
979
980 ; Get StartSector of "physical" Cluster
981 mov xl,yl
982 mov xh,yh
983 rcall fat_gethostsec
984
985 ; Found the physical sector
986 .if FAT16_DBG_FAT > 0
987 printstring "Found phys. Sector at:"
988 mov temp,yl
989 mov temp2,yh
990 lcall printhexw
991 mov temp,xl
992 mov temp2,xh
993 lcall printhexw
994 printnewline
995 .endif
996
997 ; Save the found Sector for later use into cache
998 sts fat_clust_ptr ,xl
999 sts fat_clust_ptr+1,xh
1000 sts fat_clust_ptr+2,yl
1001 sts fat_clust_ptr+3,yh
1002
1003 ; Add- Subsector to Startsector
1004 fat_add_offset:
1005 lds zl,fat_clust_offset
1006 add xl,zl
1007 adc xh,_0
1008 adc yl,_0
1009 adc yh,_0
1010
1011 ; Found the physical sector
1012 .if FAT16_DBG_FAT > 0
1013 printstring "Sector with Offset at:"
1014 mov temp,yl
1015 mov temp2,yh
1016 lcall printhexw
1017 mov temp,xl
1018 mov temp2,xh
1019 lcall printhexw
1020 printnewline
1021 .endif
1022
1023 ori temp,255
1024 fat_hpex:
1025 ret
1026
1027 ; ============================================================================
1028 ; Function: Does a Disk write operation
1029 ; ============================================================================
1030 ; Registers: [out] temp Error-Variable ( 0= No Error)
1031 ; Variables: [in] hostdsk host disk #, (partition #)
1032 ; [in] hostlba host block #, relative to part.start
1033 ; [in] hostbuf Sector to be written
1034 ; ----------------------------------------------------------------------------
1035 ; Description:
1036 ; This Routine writes a Sector to the Imagefile inside an FAT16 Partition.
1037 ; ============================================================================
1038
1039 fat_writehost:
1040 .if FAT16_RWDEBUG > 1
1041 printnewline
1042 printstring "host write "
1043 .endif
1044 rcall fat_hostparam
1045 breq fat_rdwr_err
1046
1047 call mmcWriteSect
1048 tst temp
1049 breq fat_rdwr_ok
1050
1051 rjmp fat_rdwr_err ; skip disk change detection code
1052
1053 ; After a second thought, the following code doesn't make sense, because
1054 ; disk change (change of one or more disk images) can not reliably detected.
1055 ; At least with the existing code.
1056
1057
1058
1059 rcall mgr_init_partitions
1060 cbr temp,0x80
1061 breq fat_rdwr_err
1062
1063 rcall fat_hostparam
1064 breq fat_rdwr_err
1065 call mmcWriteSect ; disabled till read is functioning
1066 tst temp
1067 brne fat_rdwr_err
1068 rjmp fat_rdwr_ok
1069
1070 fat_rdwr_ok:
1071 sts erflag,_0
1072 ret
1073
1074 fat_rdwr_err:
1075 sts erflag,_255
1076 ret
1077
1078 ; ============================================================================
1079 ; Function: Does a Disk read operation
1080 ; ============================================================================
1081 ; Registers: none
1082 ; Variables: [in] hostdsk host disk #, (partition #)
1083 ; [in] hostlba host block #, relative to part.start
1084 ; [out] hostbuf Sector read by this routine
1085 ; ----------------------------------------------------------------------------
1086 ; Description:
1087 ; This Routine reads a Sector from the Imagefile inside an FAT16 Partition.
1088 ; ============================================================================
1089
1090 fat_readhost:
1091 .if FAT16_RWDEBUG > 1
1092 printnewline
1093 printstring "host read "
1094 .endif
1095
1096 rcall fat_hostparam
1097 breq fat_rdwr_err
1098
1099
1100 .if FAT16_RWDEBUG > 0
1101 printstring "Read Image Sector:"
1102 push temp4
1103 push temp3
1104 push temp2
1105 push temp
1106 movw temp,x
1107 movw temp3,y
1108 lcall print_ultoa
1109 pop temp
1110 pop temp2
1111 pop temp3
1112 pop temp4
1113 printnewline
1114 .endif
1115
1116 lcall mmcReadSect
1117 tst temp
1118 breq fat_rdwr_ok
1119
1120 rjmp fat_rdwr_err ; skip disk change detection code
1121
1122 rcall mgr_init_partitions
1123 cbr temp,0x80
1124 breq fat_rdwr_err
1125
1126 rcall fat_hostparam
1127 breq fat_rdwr_err
1128 lcall mmcReadSect
1129 tst temp
1130 brne fat_rdwr_err
1131
1132 #endif
1133
1134 ; vim:set ts=8 noet nowrap
1135