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