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