]> cloudbase.mooo.com Git - avrcpm.git/blob - avr/dsk_fat16.asm
* avr/dsk_fat16.asm
[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,2013 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_vars:
62 fat_partfound: .byte 1 ; (partition: 0= no found 0xff=found )
63 fat_parttbl: .byte 4 ; first fat16 partition entry
64 ; only startsector is needed
65 fat_clustersize: .byte 1 ; sectors per cluster
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.
71 */
72 fat_last_dsk: .byte 1 ; number of disk with entry in cache
73 fat_log_clust: .byte 2 ; last searched logical cluster
74 fat_clust_offset: .byte 1 ; offset within the cluster
75 fat_clust_ptr: .byte 4 ; sector of last real cluster
76
77 .equ o_fat_partfound = 0
78 .equ o_fat_parttbl = 1
79 .equ o_fat_clustersize = 5
80 .equ o_fat_ptr2fat = 6
81 .equ o_fat_ptr2dat = 10
82 .equ o_fat_last_dsk = 14
83 .equ o_fat_log_clust = 15
84 .equ o_fat_clust_offset= 17
85 .equ o_fat_clust_ptr = 18
86
87
88 ; ############################################################################
89 ; Start of Code Segment
90 ; ############################################################################
91
92 .cseg
93
94 fat_cfname: .db FAT16_IMAGENAME_PREFIX, 0
95 fat_cfext: .db FAT16_IMAGENAME_SUFFIX, 0
96
97
98 ; ============================================================================
99 ; Function: Initialize internal FAT-Partition Variables
100 ; ============================================================================
101 ; Parameters
102 ; ----------------------------------------------------------------------------
103 ; Registers : none
104 ; Variables : [out] fat_parttabl
105 ; ----------------------------------------------------------------------------
106 ; Description:
107 ; This Routine initializes the internal Variables, that point to the
108 ; first Found FAT16 Partition.
109 ; ============================================================================
110 fat_init_partitiontable:
111
112 ldiw y,fat_vars
113 std y+o_fat_partfound, _0
114 std y+o_fat_parttbl+0, _0
115 std y+o_fat_parttbl+1, _0
116 std y+o_fat_parttbl+2, _0
117 std y+o_fat_parttbl+3, _0
118 ret
119
120
121 ; ============================================================================
122 ; Function: Resets the Cache
123 ; ============================================================================
124 ; Parameters
125 ; ----------------------------------------------------------------------------
126 ; Registers : none
127 ; Variables : [out] fat_log_clust
128 ; [out] fat_last_dsk
129 ; ----------------------------------------------------------------------------
130 ; Description:
131 ; This Routine resets the internal Cache- Variables. After reset, the
132 ; next read or write Command will initialize a scan of the FAT of
133 ; the FAT16-Partition for the given sector.
134 ; ============================================================================
135 fat_reset_cache:
136 ldiw y,fat_vars
137 std y+o_fat_log_clust ,_255
138 std y+o_fat_log_clust+1,_255
139 std y+o_fat_last_dsk ,_255
140 ret
141
142 ; ============================================================================
143 ; Function: Saves FAT16 Partitiondata for later Scanning
144 ; ============================================================================
145 ; Parameters
146 ; ----------------------------------------------------------------------------
147 ; Registers : [in] z Pointer to the Partitondata
148 ; Variables : [out] fat_partfound Boolean for "Partition found"
149 ; [out] fat_parttbl Pointer to Partitiontable
150 ; ----------------------------------------------------------------------------
151 ; Description:
152 ; This funktion sets the internal Variables to the Start and Size
153 ; of a given FAT16 Paritition. This Information will be used for a
154 ; later scanning of the Partition. See Function "fat_scan_partition"
155 ; for more information.
156 ; ============================================================================
157
158 fat_add_partition:
159
160 .if FAT16_DEBUG > 0
161 printstring "fat16 part found"
162 printnewline
163 .endif
164
165 ldiw y,fat_vars
166
167 ; set fat16 partition found flag
168
169 std y+o_fat_partfound,_255
170
171 ; save data from first fat16 partition
172
173 ldd temp,z+PART_START
174 std y+o_fat_parttbl,temp
175 ldd temp,z+PART_START+1
176 std y+o_fat_parttbl+1,temp
177 ldd temp,z+PART_START+2
178 std y+o_fat_parttbl+2,temp
179 ldd temp,z+PART_START+3
180 std y+o_fat_parttbl+3,temp
181
182 ret
183
184 ; ============================================================================
185 ; Read and Scann a FAT16 Partition for Imagedatefiles
186 ; ============================================================================
187 ; Registers : none
188 ; Variables : none
189 ; ----------------------------------------------------------------------------
190 ; This Routine reads the Bootblock and scanns it for a Diskimage
191 ; ============================================================================
192
193
194 fat_scan_partition:
195
196 .if FAT16_DEBUG > 0
197 printstring "fat16 scanning"
198 printnewline
199 .endif
200
201 ; Check if a FAT16 Partition was realy found
202 lds yl,fat_partfound
203 cpi yl,0
204 breq fat_scan_error
205
206
207 .if FAT16_DEBUG > 0
208 printstring "free entries in ptable ?"
209 printnewline
210 .endif
211
212 ; Check for free entries in partition table
213 lds yl,ndisks
214 cpi yl,MAXDISKS
215 brge fat_scan_error
216
217 .if FAT16_DEBUG > 0
218 printstring "read fat bootblock."
219 printnewline
220 .endif
221
222 ; Scan partition start
223 ldiw z,fat_parttbl
224 ldd xl,z+0
225 ldd xh,z+1
226 ldd yl,z+2
227 ldd yh,z+3
228
229 ; Load first sector from Partition
230 rcall mmcReadSect
231 tst temp
232 breq fat_bootblock_check
233
234 ; Read error: Block not found
235 fat_scan_error:
236 clr temp
237 ret
238
239 fat_bootblock_check:
240
241 .if FAT16_DEBUG > 0
242 printstring "fat16 bootblock check"
243 printnewline
244 .endif
245
246 ldiw y,fat_vars
247 ldiw z,hostbuf
248
249 ; get sectors per cluster from bootblock
250 ldd temp,z+FAT16_BSO_CLUSTSZ
251 std y+o_fat_clustersize,temp
252
253 .if FAT16_DEBUG > 0
254 printstring "Sectors per Cluster "
255 lcall printhex
256 printnewline
257 .endif
258
259 ; get max num of entries in root direktory from bootblock
260 ldd temp ,z+FAT16_BSO_NUMDIRENT
261 ldd temp2,z+FAT16_BSO_NUMDIRENT+1
262
263 .if FAT16_DEBUG > 0
264 printstring "Max. entries in rootdir.: "
265 lcall printhexw
266 .endif
267
268 ; Calculate begin of DATA Clusters within the Volume
269 ; Num. Dir.Sektors = (Num. of Dir. entries * 32) / Bytes per Sektor
270
271 ; Sectorsize is fixed at 512 bytes, makes 16 entries per sector
272
273
274 ; Num. Direntries / 16
275 lsr temp2
276 ror temp
277 lsr temp2
278 ror temp
279 lsr temp2
280 ror temp
281 lsr temp2
282 ror temp
283
284 push temp ;save # of rootdir sectors
285
286 .if FAT16_DEBUG > 0
287 printstring " ("
288 movw temp,_tmp0
289 lcall printhex
290 printstring " sectors)"
291 printnewline
292 .endif
293
294 .if FAT16_DEBUG > 1
295 ; Print begin of Volume
296 printstring "Begin of Volume at: "
297 ldd temp, y+o_fat_parttbl+2
298 ldd temp2,y+o_fat_parttbl+3
299 lcall printhexw
300 ldd temp, y+o_fat_parttbl+0
301 ldd temp2,y+o_fat_parttbl+1
302 lcall printhexw
303 printnewline
304 .endif
305
306 ; get num of reseved sectors from bootblock
307 ldd _tmp0,z+FAT16_BSO_RESSECT
308 ldd _tmp1,z+FAT16_BSO_RESSECT+1
309
310 ; Calculate begin of FAT within the Volume
311 ldd xl,y+o_fat_parttbl+0
312 ldd xh,y+o_fat_parttbl+1
313 ldd temp,y+o_fat_parttbl+2
314 ldd temp2,y+o_fat_parttbl+3
315
316 add xl,_tmp0
317 adc xh,_tmp1
318 adc temp,_0
319 adc temp2,_0
320
321 std y+o_fat_ptr2fat ,xl
322 std y+o_fat_ptr2fat+1,xh
323 std y+o_fat_ptr2fat+2,temp
324 std y+o_fat_ptr2fat+3,temp2
325
326 .if FAT16_DEBUG > 1
327 printstring "Begin of FAT at___: "
328 lcall printhexw
329 movw temp ,x
330 lcall printhexw
331 printnewline
332 .endif
333
334 ; get num of sectors per FAT-Table from bootblock
335 ldd temp, z+FAT16_BSO_SECPERFAT
336 ldd temp2,z+FAT16_BSO_SECPERFAT+1
337
338 .if FAT16_DEBUG > 0
339 printstring "Sectors per FAT___: "
340 lcall printhexw
341 printnewline
342 .endif
343
344 ; get num of FAT Tables from bootblock
345 ldd temp3,z+FAT16_BSO_NUMFATCP
346
347 .if FAT16_DEBUG > 0
348 printstring "Ammount of FAT copies: "
349 push temp
350 mov temp,temp3
351 lcall printhex
352 pop temp
353 printnewline
354 .endif
355
356 movw _tmp0,temp
357
358 ; Calculate begin of Root- Directory within the Volume
359
360 ldd xl, y+o_fat_ptr2fat+0
361 ldd xh, y+o_fat_ptr2fat+1
362 ldd temp, y+o_fat_ptr2fat+2
363 ldd temp2,y+o_fat_ptr2fat+3
364
365 fat_calc_dp_loop:
366 cp temp3,_0
367 breq fat_calc_dp_lend
368
369 add xl,_tmp0
370 adc xh,_tmp1
371 adc temp,_0
372 adc temp2,_0
373 dec temp3
374 rjmp fat_calc_dp_loop
375
376 fat_calc_dp_lend:
377
378 .if FAT16_DEBUG > 1
379 printstring "Begin of DIR at___: "
380 lcall printhexw
381 push temp2
382 push temp
383 movw temp,x
384 lcall printhexw
385 pop temp
386 pop temp2
387 printnewline
388 .endif
389
390 pop temp3 ;number of rootdir sectors
391
392 add xl,temp3
393 adc xh,_0
394 adc temp,_0
395 adc temp2,_0
396
397 std y+o_fat_ptr2dat ,xl
398 std y+o_fat_ptr2dat+1,xh
399 std y+o_fat_ptr2dat+2,temp
400 std y+o_fat_ptr2dat+3,temp2
401
402 .if FAT16_DEBUG > 1
403 printstring "Begin of Data at__: "
404 lcall printhexw
405 movw temp ,x
406 lcall printhexw
407 printnewline
408 .endif
409
410 ;-------------------------------------------------------------------------------
411 ; Here starts the scan of the directory for valid image files.
412
413
414 fat_next_sector_loop:
415
416 ; Get a pointer to the last+1 directory sector
417 lds xl,fat_ptr2dat
418 lds xh,fat_ptr2dat+1
419 lds yl,fat_ptr2dat+2
420 lds yh,fat_ptr2dat+3
421
422 ; Add actual offset
423 sub xl,temp3
424 sbc xh,_0
425 sbc yl,_0
426 sbc yh,_0
427
428 ; Load sector from Directory
429 lcall mmcReadSect
430 tst temp
431 breq fat_look_for_images
432
433 ; Read error: Block not found
434 clr temp
435 ret
436
437 ; Looks at a read directory block for image entries
438 fat_look_for_images:
439
440 ldiw x,hostbuf
441
442 fat_look_for_loop:
443
444 movw y,x
445 ldiw z,fat_cfname*2
446 ldi temp2,STRLEN(FAT16_IMAGENAME_PREFIX)
447 lcall strncmp_p
448 brne fat_look_continue
449
450 adiw y,1
451 adiw z,1
452 ldi temp2,STRLEN(FAT16_IMAGENAME_SUFFIX)
453 lcall strncmp_p
454 brne fat_look_continue
455
456 movw y,x
457 ldd temp2,y+STRLEN(FAT16_IMAGENAME_PREFIX)
458 ldi temp,FAT16_FIRST_IMAGENAME
459 fat_look_imgname_loop:
460 cp temp,temp2
461 breq fat_look_imgname_match
462 inc temp
463 cpi temp,FAT16_LAST_IMAGENAME+1
464 brlo fat_look_imgname_loop
465 rjmp fat_look_continue
466
467 fat_look_imgname_match:
468 rcall fat_store_new_entry
469 movw x,y
470
471 fat_look_continue:
472
473 adiw x,32
474 ldi temp,high(hostbuf+HOSTSIZE)
475 cpi xl,low(hostbuf+HOSTSIZE)
476 cpc xh,temp
477 brne fat_look_for_loop
478
479 fat_scan_next_sector:
480
481 dec temp3
482 brne fat_next_sector_loop
483
484 ret
485
486
487
488 #if 0
489 dbg_print_parttbl_raw:
490 push zh
491 push zl
492 push temp2
493 push temp
494 ldiw z,hostparttbl
495 dbg_pptblraw_lp:
496 lcall dbg_hexdump_line
497 adiw z,PARTENTRY_SIZE
498 cpi zl,low(hostparttbltop)
499 ldi temp,high(hostparttbltop)
500 cpc zh,temp
501 brne dbg_pptblraw_lp
502 pop temp
503 pop temp2
504 pop zl
505 pop zh
506 ret
507 #endif
508
509 ;-------------------------------------------------------------------------------
510 ; Create new Partition Entry
511 ; ============================================================================
512 ; Function: Create new Partition Entry
513 ; ============================================================================
514 ; Parameters: [in] yh,yl Directory entry
515 ;
516 ; ----------------------------------------------------------------------------
517 ; Registers :
518 ; Variables : [used]
519 ; [changes] temp
520 ; ----------------------------------------------------------------------------
521 ; Description:
522 ;
523 ; ============================================================================
524
525 fat_store_new_entry:
526
527 ; Found a valid image
528 .if FAT16_DEBUG > 1
529 printnewline
530 printstring "Found a valid Image! Y="
531 push temp2
532 push temp
533 movw temp ,y
534 lcall printhexw
535 pop temp
536 pop temp2
537 printnewline
538 .endif
539
540 #if 0
541 ;;;;
542 printstring "Insert entry in Tab: --> "
543 mov temp,temp2
544 lcall uartputc
545 printnewline
546 printstring "Tab before:"
547
548 rcall dbg_print_parttbl_raw
549 printnewline
550 ;;;;
551 #endif
552 ldiw z,hostparttbl
553
554 fat_st_searchpos:
555 ldd temp,z+PTAB_TYPE
556 tst temp
557 breq fat_st_insert_slot
558 sbrs temp,log2(dskType_FAT)
559 rjmp fat_st_search_next
560
561 ldd temp,z+PTAB_START+2
562 cp temp2,temp
563 brlo fat_st_ins_before
564
565 fat_st_search_next:
566 adiw z,PARTENTRY_SIZE
567 cpi zl,low(hostparttbltop)
568 ldi temp,high(hostparttbltop)
569 cpc zh,temp
570 brne fat_st_searchpos
571
572 ; Table is full.
573 #if 0
574 ;;;;
575 push temp2
576 push temp
577 printstring "Table is full. --> ptr: "
578 movw temp,z
579 lcall printhexw
580 printnewline
581 pop temp
582 pop temp2
583 ;;;;
584 #endif
585 ret
586
587 fat_st_ins_before:
588 movw x,z
589 ldiw z,hostparttbltop-PARTENTRY_SIZE
590 fat_st_insert_mkslotloop:
591 cp zl,xl
592 cpc zh,xh
593 breq fat_st_insert_slot
594
595 ld _tmp0,-z
596 std z+PARTENTRY_SIZE,_tmp0
597 rjmp fat_st_insert_mkslotloop
598
599 fat_st_insert_slot:
600
601 ; Set Type of Partition to FAT16- Fileimage
602 ldi temp,dskType_FAT
603 std z+PTAB_TYPE,temp
604
605 ; Offset to Startcluster + 2
606 ldd _tmp0,y+0x1A
607 ldd _tmp1,y+0x1B
608 std z+PTAB_START, _tmp0
609 std z+PTAB_START+1,_tmp1
610
611 std z+PTAB_START+2,temp2
612 std z+PTAB_START+3,_0
613
614 ; Convert Filesize to ammount of sectors
615 ; (calc with 512byte/sector)
616 ldd _tmp0,y+0x1C
617 ldd xl, y+0x1D
618 ldd xh, y+0x1E
619 ldd temp, y+0x1F
620
621 clc
622 cpse _tmp0,_0 ;round up
623 adiw x,1
624 adc temp,_0
625
626 lsr temp
627 ror xh
628 ror xl
629
630 adc xl,_0
631 adc xh,_0
632 adc temp,_0
633
634 ; store ammount of sectors in partitiontable
635
636 tst temp ;file size larger than 65535 sectors?
637 breq fat_add_noprune
638
639 ldi xl,255
640 ldi xh,255
641 fat_add_noprune:
642 std z+PTAB_SIZE, xl
643 std z+PTAB_SIZE+1,xh
644
645 .if FAT16_DEBUG > 1
646 ; Test finding of the first sector
647
648 push yh
649 push yl
650 ldd xl,z+1
651 ldd xh,z+2
652
653 rcall fat_gethostsec
654
655 printstring "Begin of image at: "
656 movw temp ,y
657 lcall printhexw
658 movw temp ,x
659 lcall printhexw
660 printnewline
661 pop yl
662 pop yh
663 .endif
664
665
666 ; Table counts one more entry if it was'nt allready full
667
668 lds temp,ndisks
669 cpi temp,MAXDISKS
670 breq fat_add_nomore
671 inc temp
672 sts ndisks,temp
673
674 fat_add_nomore:
675
676 #if 0
677 ;;;;
678 printnewline
679 printstring "Table now:"
680 rcall dbg_print_parttbl_raw
681 printnewline
682 ;;;;
683 #endif
684 ret
685
686
687 ; ============================================================================
688 ; Function: Cluster to HostSector
689 ; ============================================================================
690 ; Registers: [in] xl,xh Cluster Number
691 ; [out] yh,yl,xh,xl Sector Number on Disk
692 ; Variables: [in] fat_clustersize Ammount of Sectors per Cluster
693 ; [out] temp =0
694 ; ----------------------------------------------------------------------------
695 ; Description:
696 ; Calculates the logical Sectornumber given the physical ClusterNumber
697 ; and the size of a Cluster un sectors.
698 ;
699 ; ! Only works with Clustersizes 2,4,8,16,32,64,128 !
700 ; ============================================================================
701 fat_gethostsec:
702
703 ldiw y,fat_vars
704
705 ; Get Offset into Data area of Disk
706
707 clr _tmp0
708 clr _tmp1
709 sbiw x,2 ; Substract the 2 reserved clusters
710
711 ldd temp,y+o_fat_clustersize
712 lsr temp
713 fat_c2s_loop:
714 tst temp
715 breq fat_c2s_end
716 lsr temp
717
718 lsl xl
719 rol xh
720 rol _tmp0
721 rol _tmp1
722 rjmp fat_c2s_loop
723 fat_c2s_end:
724
725 ; Add begin of data area to offset
726
727 ldd temp,y+o_fat_ptr2dat+0
728 add xl,temp
729 ldd temp,y+o_fat_ptr2dat+1
730 adc xh,temp
731 ldd temp,y+o_fat_ptr2dat+2
732 adc _tmp0,temp
733 ldd temp,y+o_fat_ptr2dat+3
734 adc _tmp1,temp
735 movw y,_tmp0
736
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
774 ; Get Next Cluster from Fat
775
776 ; Trick: 512 Bytes Per Sector equals to 256 FAT- entries per Sector
777 ; so given: yl is the Offset within the FAT Sector
778 ; yh is the number off the FAT sector to Read
779
780 ; in zh,zl: Pointer to Word within the Sector to read
781 ; in yh..xl: Start sector number (LBA)
782 ; out zh,zl : word thats been read
783
784 push xl
785 push xh
786
787 ; Create FAT Offset Value
788 clr zh
789 mov zl,yl
790 lsl zl
791 rol zh
792 ; Get FAT Start
793 mov temp,yh
794 lds xl,fat_ptr2fat
795 lds xh,fat_ptr2fat+1
796 lds yl,fat_ptr2fat+2
797 lds yh,fat_ptr2fat+3
798 ; Add Cluster offset within sector
799 add xl,temp
800 adc xh,_0
801 adc yl,_0
802 adc yh,_0
803 lcall mmcReadWord
804
805 pop xh
806 pop xl
807
808 movw y,z
809
810 ; Check next logical Cluster
811
812 sbiw x,1
813 rjmp fat_next_phsy_clust
814
815 ; Found the physical cluster
816 fat_found_phsy_clust:
817
818 .if FAT16_DBG_FAT > 0
819 printstring "Found phys. Cluster at:"
820 movw temp,y
821 lcall printhexw
822 printnewline
823 .endif
824
825 ret
826
827 ; ============================================================================
828 ; Function: This Routine searches for the Sector within an Imagefile
829 ; ============================================================================
830 ; Registers: [out] xl,xh,yl,yh Pointer to the sector on the SD-Card
831 ; [out] temp Error variable (0= No Error)
832 ; Variables: [in] hostdsk host disk #, (partition #)
833 ; [in] hostlba host block #, relative to part.start
834 ; [in] fat_last_dsk number of disk with entry in cache
835 ; [in] fat_log_clust last searched logical cluster
836 ; [in] fat_clust_offset offset within the cluster
837 ; [in] fat_clust_ptr sector of last real cluster
838 ; ----------------------------------------------------------------------------
839 ; Description:
840 ; This routine uses the variables hostdsk and hostlba to find an sector
841 ; in the imagefile.
842 ; The CP/M sector given within "hostlba" are splited to a logical cluster-
843 ; number and the subsector within this logical cluster.
844 ; logical cluster number = hostlba / fat_clustersize
845 ; The logical cluster number will be compared to the logical cluster number
846 ; within the cache. When this clusters are the same and the diskid's are
847 ; also the same, then the cached physical sector will be used.
848 ; When the clusters or the disks don't match, a seek for the physical
849 ; cluster is performed. This seek is done thru an access over the fat of
850 ; the fat16 partition. the routine starts at the first cluster of the
851 ; imagefile and goes along the linked list of clusternumber till it reaches
852 ; the searched cluster. The found clusternumber will be used to calculate
853 ; the sektor where this cluster lies on the sd card. Both the found physical
854 ; cluster and the logical cluster together with the physical sectornumber
855 ; are stored in the cache.
856 ; The last step done is to add the subsectoroffset to the found physical
857 ; sector. this gives the pointer to the sector to be read and or written.
858 ; ============================================================================
859
860 fat_hostparam:
861 lds zl,hostdsk
862 rcall dsk_getpartentry ; get partition entry
863
864 fat_hostlend:
865 lds temp ,hostlba
866 lds temp2,hostlba+1
867
868
869 ldd xl,z+5 ; get size of disk in sectors
870 ldd xh,z+6
871
872 cp temp,xl ; check given sector against disksize
873 cpc temp2,xh
874 brcs fat_hp1
875
876 clr temp
877 ret
878
879 fat_hp1:
880 ; ################# Get logical Number of Cluster within the imagefile
881 ; printstring "calc log sector"
882 ; Get logical Sectornumber from temp
883 movw x,temp
884 mov yl,_0
885 mov yh,_0
886 ; Divide logical Sectornumber by size of Cluster in sectors
887 lds zl,fat_clustersize
888 lsr zl
889 fat_search_clst_lp:
890 tst zl
891 breq fat_found_clst
892
893 lsr yh
894 ror yl
895 ror xh
896 ror xl
897
898 lsr zl
899
900 rjmp fat_search_clst_lp
901
902 fat_found_clst:
903 ; at this point xh and xl are carying the logical cluster number
904 ; printstring "find subsector"
905 ; ################# Get subsector within the logical cluster for later use
906 mov yl,xl
907 lds zl,fat_clustersize
908 lsr zl
909 fat_search_clst_lp2:
910 tst zl
911 breq fat_found_subsec
912 lsl yl
913
914 lsr zl
915 rjmp fat_search_clst_lp2
916
917 fat_found_subsec:
918 mov zl,temp
919 sub zl,yl
920 sts fat_clust_offset,zl
921
922 ; Check against last HOSTDISK searched
923 lds yl,fat_last_dsk
924 lds yh,hostdsk
925 cp yl,yh
926 brne fat_wrong_cache_clst
927
928 ; Check against last Cluster searched
929 lds yl,fat_log_clust
930 lds yh,fat_log_clust+1
931
932 cp yl,xl
933 cpc 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