trunk/src/mess/tools/imgtool/modules/ti99.c
| r17926 | r17927 | |
| 1505 | 1505 | L2I_DSK, |
| 1506 | 1506 | L2I_WIN |
| 1507 | 1507 | }; |
| 1508 | | struct u |
| 1508 | |
| 1509 | struct ti99_lvl2_imgref |
| 1509 | 1510 | { |
| 1510 | 1511 | ti99_lvl1_imgref l1_img;/* image format, imgtool image handle, image geometry */ |
| 1511 | 1512 | ti99_AUformat AUformat; /* AU format */ |
| r17926 | r17927 | |
| 1536 | 1537 | ti99_lvl2_imgref_dsk dsk; |
| 1537 | 1538 | ti99_lvl2_imgref_win win; |
| 1538 | 1539 | }; /* structure-specific info */ |
| 1539 | | } ti99_lvl2_imgref; |
| 1540 | }; |
| 1540 | 1541 | |
| 1541 | 1542 | /* |
| 1542 | 1543 | file flags found in fdr (and tifiles) |
| r17926 | r17927 | |
| 1704 | 1705 | */ |
| 1705 | 1706 | struct ti99_lvl2_fileref_dsk |
| 1706 | 1707 | { |
| 1707 | | ti99_lvl2_imgref *l2_img; |
| 1708 | struct ti99_lvl2_imgref *l2_img; |
| 1708 | 1709 | int fdr_aphysrec; |
| 1709 | 1710 | dsk_fdr fdr; |
| 1710 | 1711 | }; |
| 1711 | 1712 | |
| 1712 | 1713 | struct ti99_lvl2_fileref_win |
| 1713 | 1714 | { |
| 1714 | | ti99_lvl2_imgref *l2_img; |
| 1715 | struct ti99_lvl2_imgref *l2_img; |
| 1715 | 1716 | unsigned fphysrecs; /* copy of field in the eldest FDR */ |
| 1716 | 1717 | unsigned eldestfdr_aphysrec; /* aphysrec address of the eldest FDR */ |
| 1717 | 1718 | unsigned curfdr_aphysrec; /* aphysrec address of the currently open sibling FDR */ |
| r17926 | r17927 | |
| 1730 | 1731 | L2F_WIN, |
| 1731 | 1732 | L2F_TIFILES |
| 1732 | 1733 | }; |
| 1733 | | struct u |
| 1734 | |
| 1735 | struct ti99_lvl2_fileref |
| 1734 | 1736 | { |
| 1735 | 1737 | l2f_type_t type; |
| 1736 | 1738 | union |
| r17926 | r17927 | |
| 1739 | 1741 | ti99_lvl2_fileref_win win; |
| 1740 | 1742 | ti99_lvl2_fileref_tifiles tifiles; |
| 1741 | 1743 | }; |
| 1742 | | } ti99_lvl2_fileref; |
| 1744 | }; |
| 1743 | 1745 | |
| 1744 | | |
| 1745 | | |
| 1746 | 1746 | /* |
| 1747 | 1747 | Compare two (possibly empty) catalog entry for qsort |
| 1748 | 1748 | */ |
| r17926 | r17927 | |
| 1785 | 1785 | |
| 1786 | 1786 | Return an error code if there was an error, 0 otherwise. |
| 1787 | 1787 | */ |
| 1788 | | static int dsk_read_catalog(ti99_lvl2_imgref *l2_img, int aphysrec, ti99_catalog *dest) |
| 1788 | static int dsk_read_catalog(struct ti99_lvl2_imgref *l2_img, int aphysrec, ti99_catalog *dest) |
| 1789 | 1789 | { |
| 1790 | | int totphysrecs = l2_img->u.dsk.totphysrecs; |
| 1790 | int totphysrecs = l2_img->dsk.totphysrecs; |
| 1791 | 1791 | UINT16BE fdir_buf[128]; |
| 1792 | 1792 | dsk_fdr fdr; |
| 1793 | 1793 | int i; |
| r17926 | r17927 | |
| 1856 | 1856 | |
| 1857 | 1857 | Return an error code if there was an error, 0 otherwise. |
| 1858 | 1858 | */ |
| 1859 | | static int win_read_catalog(ti99_lvl2_imgref *l2_img, int DDR_AU, ti99_catalog *dest) |
| 1859 | static int win_read_catalog(struct ti99_lvl2_imgref *l2_img, int DDR_AU, ti99_catalog *dest) |
| 1860 | 1860 | { |
| 1861 | 1861 | win_vib_ddr ddr_buf; |
| 1862 | 1862 | UINT16BE fdir_buf[128]; |
| r17926 | r17927 | |
| 1979 | 1979 | out_is_dir: TRUE if element is a directory |
| 1980 | 1980 | catalog_index: on output, index of file catalog entry (may be NULL) |
| 1981 | 1981 | */ |
| 1982 | | static int dsk_find_catalog_entry(ti99_lvl2_imgref *l2_img, const char *fpath, int *parent_ref_valid, int *parent_ref, int *out_is_dir, int *catalog_index) |
| 1982 | static int dsk_find_catalog_entry(struct ti99_lvl2_imgref *l2_img, const char *fpath, int *parent_ref_valid, int *parent_ref, int *out_is_dir, int *catalog_index) |
| 1983 | 1983 | { |
| 1984 | 1984 | int i; |
| 1985 | 1985 | const ti99_catalog *cur_catalog; |
| r17926 | r17927 | |
| 1989 | 1989 | int is_dir = FALSE; |
| 1990 | 1990 | |
| 1991 | 1991 | |
| 1992 | | cur_catalog = & l2_img->u.dsk.catalogs[0]; |
| 1992 | cur_catalog = & l2_img->dsk.catalogs[0]; |
| 1993 | 1993 | if (parent_ref_valid) |
| 1994 | 1994 | (* parent_ref_valid) = FALSE; |
| 1995 | 1995 | if (parent_ref) |
| r17926 | r17927 | |
| 2049 | 2049 | return IMGTOOLERR_BADFILENAME; |
| 2050 | 2050 | |
| 2051 | 2051 | /* initialize cur_catalog */ |
| 2052 | | cur_catalog = & l2_img->u.dsk.catalogs[i+1]; |
| 2052 | cur_catalog = & l2_img->dsk.catalogs[i+1]; |
| 2053 | 2053 | if (parent_ref) |
| 2054 | 2054 | *parent_ref = i+1; |
| 2055 | 2055 | } |
| r17926 | r17927 | |
| 2079 | 2079 | out_is_dir: TRUE if element is a directory |
| 2080 | 2080 | catalog_index: on output, index of file catalog entry (may be NULL) |
| 2081 | 2081 | */ |
| 2082 | | static int win_find_catalog_entry(ti99_lvl2_imgref *l2_img, const char *fpath, |
| 2082 | static int win_find_catalog_entry(struct ti99_lvl2_imgref *l2_img, const char *fpath, |
| 2083 | 2083 | int *parent_ref_valid, int *parent_ddr_AU, ti99_catalog *parent_catalog, |
| 2084 | 2084 | int *out_is_dir, int *catalog_index) |
| 2085 | 2085 | { |
| r17926 | r17927 | |
| 2179 | 2179 | l2_img: image reference |
| 2180 | 2180 | fdr_AU: on output, address of allocated AU |
| 2181 | 2181 | */ |
| 2182 | | static int alloc_fdr_AU(ti99_lvl2_imgref *l2_img, unsigned *fdr_AU) |
| 2182 | static int alloc_fdr_AU(struct ti99_lvl2_imgref *l2_img, unsigned *fdr_AU) |
| 2183 | 2183 | { |
| 2184 | 2184 | int totAUs = l2_img->AUformat.totAUs; |
| 2185 | 2185 | int i; |
| r17926 | r17927 | |
| 2198 | 2198 | return IMGTOOLERR_NOSPACE; |
| 2199 | 2199 | } |
| 2200 | 2200 | |
| 2201 | | INLINE int get_dsk_fdr_cluster_baseAU(ti99_lvl2_imgref *l2_img, dsk_fdr *fdr, int cluster_index) |
| 2201 | INLINE int get_dsk_fdr_cluster_baseAU(struct ti99_lvl2_imgref *l2_img, dsk_fdr *fdr, int cluster_index) |
| 2202 | 2202 | { |
| 2203 | 2203 | int reply; |
| 2204 | 2204 | |
| r17926 | r17927 | |
| 2211 | 2211 | return reply; |
| 2212 | 2212 | } |
| 2213 | 2213 | |
| 2214 | | INLINE int get_dsk_fdr_cluster_baseaphysrec(ti99_lvl2_imgref *l2_img, dsk_fdr *fdr, int cluster_index) |
| 2214 | INLINE int get_dsk_fdr_cluster_baseaphysrec(struct ti99_lvl2_imgref *l2_img, dsk_fdr *fdr, int cluster_index) |
| 2215 | 2215 | { |
| 2216 | 2216 | int reply; |
| 2217 | 2217 | |
| r17926 | r17927 | |
| 2235 | 2235 | fdr->clusters[cluster_index][2] = data >> 4; |
| 2236 | 2236 | } |
| 2237 | 2237 | |
| 2238 | | INLINE void set_dsk_fdr_cluster(ti99_lvl2_imgref *l2_img, dsk_fdr *fdr, int cluster_index, int baseAU, int lastfphysrec) |
| 2238 | INLINE void set_dsk_fdr_cluster(struct ti99_lvl2_imgref *l2_img, dsk_fdr *fdr, int cluster_index, int baseAU, int lastfphysrec) |
| 2239 | 2239 | { |
| 2240 | 2240 | /* convert AU address to FDR value */ |
| 2241 | 2241 | if (l2_img->AUformat.physrecsperAU <= 2) |
| r17926 | r17927 | |
| 2269 | 2269 | set_UINT16LE(&fdr->fixrecs_LSW, data & 0xffff); |
| 2270 | 2270 | } |
| 2271 | 2271 | |
| 2272 | | INLINE unsigned get_win_fdr_prevsibFDR_aphysrec(ti99_lvl2_imgref *l2_img, win_fdr *fdr) |
| 2272 | INLINE unsigned get_win_fdr_prevsibFDR_aphysrec(struct ti99_lvl2_imgref *l2_img, win_fdr *fdr) |
| 2273 | 2273 | { |
| 2274 | 2274 | unsigned prevsibFDR_AU = get_UINT16BE(fdr->prevsibFDR_AU); |
| 2275 | 2275 | |
| r17926 | r17927 | |
| 2278 | 2278 | : 0; |
| 2279 | 2279 | } |
| 2280 | 2280 | |
| 2281 | | INLINE unsigned get_win_fdr_nextsibFDR_aphysrec(ti99_lvl2_imgref *l2_img, win_fdr *fdr) |
| 2281 | INLINE unsigned get_win_fdr_nextsibFDR_aphysrec(struct ti99_lvl2_imgref *l2_img, win_fdr *fdr) |
| 2282 | 2282 | { |
| 2283 | 2283 | unsigned nextsibFDR_AU = get_UINT16BE(fdr->nextsibFDR_AU); |
| 2284 | 2284 | |
| r17926 | r17927 | |
| 2795 | 2795 | /* |
| 2796 | 2796 | Allocate a new (empty) file |
| 2797 | 2797 | */ |
| 2798 | | static int new_file_lvl2_dsk(ti99_lvl2_imgref *l2_img, int parent_ref, char filename[10], ti99_lvl2_fileref *l2_file) |
| 2798 | static int new_file_lvl2_dsk(struct ti99_lvl2_imgref *l2_img, int parent_ref, char filename[10], struct ti99_lvl2_fileref *l2_file) |
| 2799 | 2799 | { |
| 2800 | | ti99_catalog *catalog = &l2_img->u.dsk.catalogs[parent_ref]; |
| 2800 | ti99_catalog *catalog = &l2_img->dsk.catalogs[parent_ref]; |
| 2801 | 2801 | unsigned fdr_AU, fdr_aphysrec; |
| 2802 | 2802 | int catalog_index, i; |
| 2803 | 2803 | int reply = 0; |
| r17926 | r17927 | |
| 2842 | 2842 | |
| 2843 | 2843 | /* set up file handle */ |
| 2844 | 2844 | l2_file->type = L2F_DSK; |
| 2845 | | l2_file->u.dsk.l2_img = l2_img; |
| 2846 | | l2_file->u.dsk.fdr_aphysrec = fdr_aphysrec; |
| 2847 | | memset(&l2_file->u.dsk.fdr, 0, sizeof(l2_file->u.dsk.fdr)); |
| 2848 | | memcpy(l2_file->u.dsk.fdr.name, filename, 10); |
| 2845 | l2_file->dsk.l2_img = l2_img; |
| 2846 | l2_file->dsk.fdr_aphysrec = fdr_aphysrec; |
| 2847 | memset(&l2_file->dsk.fdr, 0, sizeof(l2_file->dsk.fdr)); |
| 2848 | memcpy(l2_file->dsk.fdr.name, filename, 10); |
| 2849 | 2849 | |
| 2850 | 2850 | return 0; |
| 2851 | 2851 | } |
| r17926 | r17927 | |
| 2853 | 2853 | /* |
| 2854 | 2854 | Allocate a new (empty) file |
| 2855 | 2855 | */ |
| 2856 | | static int new_file_lvl2_win(ti99_lvl2_imgref *l2_img, ti99_catalog *parent_catalog, char filename[10], ti99_lvl2_fileref *l2_file) |
| 2856 | static int new_file_lvl2_win(struct ti99_lvl2_imgref *l2_img, ti99_catalog *parent_catalog, char filename[10], struct ti99_lvl2_fileref *l2_file) |
| 2857 | 2857 | { |
| 2858 | 2858 | unsigned fdr_AU; |
| 2859 | 2859 | int catalog_index, i; |
| r17926 | r17927 | |
| 2894 | 2894 | |
| 2895 | 2895 | /* set up file handle */ |
| 2896 | 2896 | l2_file->type = L2F_WIN; |
| 2897 | | l2_file->u.win.l2_img = l2_img; |
| 2898 | | l2_file->u.win.fphysrecs = 0; |
| 2899 | | l2_file->u.win.eldestfdr_aphysrec = fdr_AU * l2_img->AUformat.physrecsperAU; |
| 2900 | | l2_file->u.win.curfdr_aphysrec = l2_file->u.win.eldestfdr_aphysrec; |
| 2901 | | memset(&l2_file->u.win.curfdr, 0, sizeof(l2_file->u.win.curfdr)); |
| 2902 | | memcpy(l2_file->u.win.curfdr.name, filename, 10); |
| 2897 | l2_file->win.l2_img = l2_img; |
| 2898 | l2_file->win.fphysrecs = 0; |
| 2899 | l2_file->win.eldestfdr_aphysrec = fdr_AU * l2_img->AUformat.physrecsperAU; |
| 2900 | l2_file->win.curfdr_aphysrec = l2_file->win.eldestfdr_aphysrec; |
| 2901 | memset(&l2_file->win.curfdr, 0, sizeof(l2_file->win.curfdr)); |
| 2902 | memcpy(l2_file->win.curfdr.name, filename, 10); |
| 2903 | 2903 | |
| 2904 | 2904 | return 0; |
| 2905 | 2905 | } |
| r17926 | r17927 | |
| 2907 | 2907 | /* |
| 2908 | 2908 | Allocate a new (empty) file |
| 2909 | 2909 | */ |
| 2910 | | static int new_file_lvl2_tifiles(imgtool_stream *file_handle, ti99_lvl2_fileref *l2_file) |
| 2910 | static int new_file_lvl2_tifiles(imgtool_stream *file_handle, struct ti99_lvl2_fileref *l2_file) |
| 2911 | 2911 | { |
| 2912 | 2912 | /* set up file handle */ |
| 2913 | 2913 | l2_file->type = L2F_TIFILES; |
| 2914 | | l2_file->u.tifiles.file_handle = file_handle; |
| 2915 | | memset(&l2_file->u.tifiles.hdr, 0, sizeof(l2_file->u.tifiles.hdr)); |
| 2916 | | l2_file->u.tifiles.hdr.tifiles[0] = '\7'; |
| 2917 | | l2_file->u.tifiles.hdr.tifiles[1] = 'T'; |
| 2918 | | l2_file->u.tifiles.hdr.tifiles[2] = 'I'; |
| 2919 | | l2_file->u.tifiles.hdr.tifiles[3] = 'F'; |
| 2920 | | l2_file->u.tifiles.hdr.tifiles[4] = 'I'; |
| 2921 | | l2_file->u.tifiles.hdr.tifiles[5] = 'L'; |
| 2922 | | l2_file->u.tifiles.hdr.tifiles[6] = 'E'; |
| 2923 | | l2_file->u.tifiles.hdr.tifiles[7] = 'S'; |
| 2914 | l2_file->tifiles.file_handle = file_handle; |
| 2915 | memset(&l2_file->tifiles.hdr, 0, sizeof(l2_file->tifiles.hdr)); |
| 2916 | l2_file->tifiles.hdr.tifiles[0] = '\7'; |
| 2917 | l2_file->tifiles.hdr.tifiles[1] = 'T'; |
| 2918 | l2_file->tifiles.hdr.tifiles[2] = 'I'; |
| 2919 | l2_file->tifiles.hdr.tifiles[3] = 'F'; |
| 2920 | l2_file->tifiles.hdr.tifiles[4] = 'I'; |
| 2921 | l2_file->tifiles.hdr.tifiles[5] = 'L'; |
| 2922 | l2_file->tifiles.hdr.tifiles[6] = 'E'; |
| 2923 | l2_file->tifiles.hdr.tifiles[7] = 'S'; |
| 2924 | 2924 | |
| 2925 | 2925 | return 0; |
| 2926 | 2926 | } |
| r17926 | r17927 | |
| 2932 | 2932 | fpath: access path to the file |
| 2933 | 2933 | file: set up if open is successful |
| 2934 | 2934 | */ |
| 2935 | | static int open_file_lvl2_dsk(ti99_lvl2_imgref *l2_img, const char *fpath, ti99_lvl2_fileref *l2_file) |
| 2935 | static int open_file_lvl2_dsk(struct ti99_lvl2_imgref *l2_img, const char *fpath, struct ti99_lvl2_fileref *l2_file) |
| 2936 | 2936 | { |
| 2937 | 2937 | int parent_ref, is_dir, catalog_index; |
| 2938 | 2938 | int reply; |
| r17926 | r17927 | |
| 2947 | 2947 | return IMGTOOLERR_BADFILENAME; |
| 2948 | 2948 | |
| 2949 | 2949 | l2_file->type = L2F_DSK; |
| 2950 | | l2_file->u.dsk.l2_img = l2_img; |
| 2951 | | l2_file->u.dsk.fdr_aphysrec = l2_img->u.dsk.catalogs[parent_ref].files[catalog_index].fdr_ptr; |
| 2952 | | if (read_absolute_physrec(& l2_img->l1_img, l2_file->u.dsk.fdr_aphysrec, &l2_file->u.dsk.fdr)) |
| 2950 | l2_file->dsk.l2_img = l2_img; |
| 2951 | l2_file->dsk.fdr_aphysrec = l2_img->dsk.catalogs[parent_ref].files[catalog_index].fdr_ptr; |
| 2952 | if (read_absolute_physrec(& l2_img->l1_img, l2_file->dsk.fdr_aphysrec, &l2_file->dsk.fdr)) |
| 2953 | 2953 | return IMGTOOLERR_READERROR; |
| 2954 | 2954 | |
| 2955 | 2955 | return 0; |
| r17926 | r17927 | |
| 2962 | 2962 | fpath: access path to the file |
| 2963 | 2963 | file: set up if open is successful |
| 2964 | 2964 | */ |
| 2965 | | static int open_file_lvl2_win(ti99_lvl2_imgref *l2_img, const char *fpath, ti99_lvl2_fileref *l2_file) |
| 2965 | static int open_file_lvl2_win(struct ti99_lvl2_imgref *l2_img, const char *fpath, struct ti99_lvl2_fileref *l2_file) |
| 2966 | 2966 | { |
| 2967 | 2967 | int parent_ref, is_dir, catalog_index; |
| 2968 | 2968 | ti99_catalog catalog; |
| r17926 | r17927 | |
| 2977 | 2977 | return IMGTOOLERR_BADFILENAME; |
| 2978 | 2978 | |
| 2979 | 2979 | l2_file->type = L2F_WIN; |
| 2980 | | l2_file->u.win.l2_img = l2_img; |
| 2981 | | l2_file->u.win.eldestfdr_aphysrec = catalog.files[catalog_index].fdr_ptr * l2_img->AUformat.physrecsperAU; |
| 2982 | | l2_file->u.win.curfdr_aphysrec = l2_file->u.win.eldestfdr_aphysrec; |
| 2983 | | if (read_absolute_physrec(& l2_img->l1_img, l2_file->u.win.curfdr_aphysrec, &l2_file->u.win.curfdr)) |
| 2980 | l2_file->win.l2_img = l2_img; |
| 2981 | l2_file->win.eldestfdr_aphysrec = catalog.files[catalog_index].fdr_ptr * l2_img->AUformat.physrecsperAU; |
| 2982 | l2_file->win.curfdr_aphysrec = l2_file->win.eldestfdr_aphysrec; |
| 2983 | if (read_absolute_physrec(& l2_img->l1_img, l2_file->win.curfdr_aphysrec, &l2_file->win.curfdr)) |
| 2984 | 2984 | return IMGTOOLERR_READERROR; |
| 2985 | | l2_file->u.win.fphysrecs = get_win_fdr_fphysrecs(&l2_file->u.win.curfdr); |
| 2985 | l2_file->win.fphysrecs = get_win_fdr_fphysrecs(&l2_file->win.curfdr); |
| 2986 | 2986 | |
| 2987 | 2987 | /* check integrity of FDR sibling chain */ |
| 2988 | 2988 | /* note that as we check that the back chain is consistent with the forward |
| 2989 | 2989 | chain, we will also detect any cycle in the sibling chain, so we do not |
| 2990 | 2990 | need to check against them explicitely */ |
| 2991 | | if (get_UINT16BE(l2_file->u.win.curfdr.prevsibFDR_AU) != 0) |
| 2991 | if (get_UINT16BE(l2_file->win.curfdr.prevsibFDR_AU) != 0) |
| 2992 | 2992 | return IMGTOOLERR_CORRUPTIMAGE; |
| 2993 | 2993 | |
| 2994 | 2994 | { |
| r17926 | r17927 | |
| 2999 | 2999 | |
| 3000 | 3000 | cur_fphysrec = 0; |
| 3001 | 3001 | pastendoflist_flag = 0; |
| 3002 | | cur_fdr = &l2_file->u.win.curfdr; |
| 3003 | | curfdr_aphysrec = l2_file->u.win.eldestfdr_aphysrec; |
| 3002 | cur_fdr = &l2_file->win.curfdr; |
| 3003 | curfdr_aphysrec = l2_file->win.eldestfdr_aphysrec; |
| 3004 | 3004 | |
| 3005 | 3005 | while (1) |
| 3006 | 3006 | { |
| r17926 | r17927 | |
| 3037 | 3037 | return IMGTOOLERR_CORRUPTIMAGE; |
| 3038 | 3038 | |
| 3039 | 3039 | /* update current file physrec position to point to end of sibling FDR */ |
| 3040 | | cur_fphysrec += sibFDR_AUlen * l2_file->u.win.l2_img->AUformat.physrecsperAU; |
| 3040 | cur_fphysrec += sibFDR_AUlen * l2_file->win.l2_img->AUformat.physrecsperAU; |
| 3041 | 3041 | |
| 3042 | 3042 | /* exit loop if end of sibling chain */ |
| 3043 | 3043 | if (! get_UINT16BE(cur_fdr->nextsibFDR_AU)) |
| 3044 | 3044 | break; |
| 3045 | 3045 | |
| 3046 | 3046 | /* otherwise read next FDR */ |
| 3047 | | if (get_UINT16BE(cur_fdr->nextsibFDR_AU) >= l2_file->u.win.l2_img->AUformat.totAUs) |
| 3047 | if (get_UINT16BE(cur_fdr->nextsibFDR_AU) >= l2_file->win.l2_img->AUformat.totAUs) |
| 3048 | 3048 | return IMGTOOLERR_CORRUPTIMAGE; |
| 3049 | 3049 | |
| 3050 | 3050 | prevfdr_aphysrec = curfdr_aphysrec; |
| 3051 | | curfdr_aphysrec = get_win_fdr_nextsibFDR_aphysrec(l2_file->u.win.l2_img, cur_fdr); |
| 3052 | | if (read_absolute_physrec(& l2_file->u.win.l2_img->l1_img, curfdr_aphysrec, &fdr_buf)) |
| 3051 | curfdr_aphysrec = get_win_fdr_nextsibFDR_aphysrec(l2_file->win.l2_img, cur_fdr); |
| 3052 | if (read_absolute_physrec(& l2_file->win.l2_img->l1_img, curfdr_aphysrec, &fdr_buf)) |
| 3053 | 3053 | return IMGTOOLERR_READERROR; |
| 3054 | 3054 | cur_fdr = &fdr_buf; |
| 3055 | 3055 | |
| 3056 | 3056 | /* check that back chaining is consistent with forward chaining */ |
| 3057 | | if (get_win_fdr_prevsibFDR_aphysrec(l2_file->u.win.l2_img, &fdr_buf) != prevfdr_aphysrec) |
| 3057 | if (get_win_fdr_prevsibFDR_aphysrec(l2_file->win.l2_img, &fdr_buf) != prevfdr_aphysrec) |
| 3058 | 3058 | return IMGTOOLERR_CORRUPTIMAGE; |
| 3059 | 3059 | /* check fphysrecs field */ |
| 3060 | 3060 | if (get_win_fdr_fphysrecs(&fdr_buf) != cur_fphysrec) |
| 3061 | 3061 | return IMGTOOLERR_CORRUPTIMAGE; |
| 3062 | 3062 | |
| 3063 | 3063 | /* check consistency of informative fields (name, record format, flags, etc) */ |
| 3064 | | if (memcmp(fdr_buf.name, l2_file->u.win.curfdr.name, 10) |
| 3065 | | || (get_UINT16BE(fdr_buf.xreclen) != get_UINT16BE(l2_file->u.win.curfdr.xreclen)) |
| 3066 | | || (fdr_buf.flags != l2_file->u.win.curfdr.flags) |
| 3067 | | || (fdr_buf.recsperphysrec != l2_file->u.win.curfdr.recsperphysrec) |
| 3068 | | || (fdr_buf.eof != l2_file->u.win.curfdr.eof) |
| 3069 | | || (fdr_buf.reclen != l2_file->u.win.curfdr.reclen) |
| 3070 | | || (get_UINT16LE(fdr_buf.fixrecs_LSW) != get_UINT16LE(l2_file->u.win.curfdr.fixrecs_LSW)) |
| 3071 | | || memcmp(&fdr_buf.creation, &l2_file->u.win.curfdr.creation, 4) |
| 3072 | | || memcmp(&fdr_buf.update, &l2_file->u.win.curfdr.update, 4) |
| 3073 | | /*|| memcmp(fdr_buf.id, l2_file->u.win.curfdr.id, 2)*/ |
| 3074 | | || (get_UINT16BE(fdr_buf.parent_FDIR_AU) != get_UINT16BE(l2_file->u.win.curfdr.parent_FDIR_AU)) |
| 3075 | | || ((fdr_buf.xinfo_MSB & 0xf) != (l2_file->u.win.curfdr.xinfo_MSB & 0xf))) |
| 3064 | if (memcmp(fdr_buf.name, l2_file->win.curfdr.name, 10) |
| 3065 | || (get_UINT16BE(fdr_buf.xreclen) != get_UINT16BE(l2_file->win.curfdr.xreclen)) |
| 3066 | || (fdr_buf.flags != l2_file->win.curfdr.flags) |
| 3067 | || (fdr_buf.recsperphysrec != l2_file->win.curfdr.recsperphysrec) |
| 3068 | || (fdr_buf.eof != l2_file->win.curfdr.eof) |
| 3069 | || (fdr_buf.reclen != l2_file->win.curfdr.reclen) |
| 3070 | || (get_UINT16LE(fdr_buf.fixrecs_LSW) != get_UINT16LE(l2_file->win.curfdr.fixrecs_LSW)) |
| 3071 | || memcmp(&fdr_buf.creation, &l2_file->win.curfdr.creation, 4) |
| 3072 | || memcmp(&fdr_buf.update, &l2_file->win.curfdr.update, 4) |
| 3073 | /*|| memcmp(fdr_buf.id, l2_file->win.curfdr.id, 2)*/ |
| 3074 | || (get_UINT16BE(fdr_buf.parent_FDIR_AU) != get_UINT16BE(l2_file->win.curfdr.parent_FDIR_AU)) |
| 3075 | || ((fdr_buf.xinfo_MSB & 0xf) != (l2_file->win.curfdr.xinfo_MSB & 0xf))) |
| 3076 | 3076 | return IMGTOOLERR_CORRUPTIMAGE; |
| 3077 | 3077 | } |
| 3078 | | if (cur_fphysrec < l2_file->u.win.fphysrecs) |
| 3078 | if (cur_fphysrec < l2_file->win.fphysrecs) |
| 3079 | 3079 | return IMGTOOLERR_CORRUPTIMAGE; |
| 3080 | 3080 | } |
| 3081 | 3081 | |
| r17926 | r17927 | |
| 3085 | 3085 | /* |
| 3086 | 3086 | Open an existing file in TIFILES format |
| 3087 | 3087 | */ |
| 3088 | | static int open_file_lvl2_tifiles(imgtool_stream *file_handle, ti99_lvl2_fileref *l2_file) |
| 3088 | static int open_file_lvl2_tifiles(imgtool_stream *file_handle, struct ti99_lvl2_fileref *l2_file) |
| 3089 | 3089 | { |
| 3090 | 3090 | /* set up file handle */ |
| 3091 | 3091 | l2_file->type = L2F_TIFILES; |
| 3092 | | l2_file->u.tifiles.file_handle = file_handle; |
| 3092 | l2_file->tifiles.file_handle = file_handle; |
| 3093 | 3093 | |
| 3094 | 3094 | /* seek to header */ |
| 3095 | | if (stream_seek(l2_file->u.tifiles.file_handle, 0, SEEK_SET)) |
| 3095 | if (stream_seek(l2_file->tifiles.file_handle, 0, SEEK_SET)) |
| 3096 | 3096 | return IMGTOOLERR_READERROR; |
| 3097 | 3097 | /* read it */ |
| 3098 | | if (stream_read(l2_file->u.tifiles.file_handle, &l2_file->u.tifiles.hdr, sizeof(l2_file->u.tifiles.hdr)) != sizeof(l2_file->u.tifiles.hdr)) |
| 3098 | if (stream_read(l2_file->tifiles.file_handle, &l2_file->tifiles.hdr, sizeof(l2_file->tifiles.hdr)) != sizeof(l2_file->tifiles.hdr)) |
| 3099 | 3099 | return IMGTOOLERR_READERROR; |
| 3100 | 3100 | |
| 3101 | 3101 | return 0; |
| r17926 | r17927 | |
| 3211 | 3211 | /* |
| 3212 | 3212 | read a 256-byte physical record from a file |
| 3213 | 3213 | */ |
| 3214 | | static int read_file_physrec(ti99_lvl2_fileref *l2_file, unsigned fphysrec, void *dest) |
| 3214 | static int read_file_physrec(struct ti99_lvl2_fileref *l2_file, unsigned fphysrec, void *dest) |
| 3215 | 3215 | { |
| 3216 | 3216 | int errorcode; |
| 3217 | 3217 | unsigned aphysrec; |
| r17926 | r17927 | |
| 3220 | 3220 | { |
| 3221 | 3221 | case L2F_DSK: |
| 3222 | 3222 | /* compute absolute physrec address */ |
| 3223 | | errorcode = dsk_fphysrec_to_aphysrec(&l2_file->u.dsk, fphysrec, &aphysrec); |
| 3223 | errorcode = dsk_fphysrec_to_aphysrec(&l2_file->dsk, fphysrec, &aphysrec); |
| 3224 | 3224 | if (errorcode) |
| 3225 | 3225 | return errorcode; |
| 3226 | 3226 | /* read physrec */ |
| 3227 | | if (read_absolute_physrec(& l2_file->u.dsk.l2_img->l1_img, aphysrec, dest)) |
| 3227 | if (read_absolute_physrec(& l2_file->dsk.l2_img->l1_img, aphysrec, dest)) |
| 3228 | 3228 | return IMGTOOLERR_READERROR; |
| 3229 | 3229 | break; |
| 3230 | 3230 | |
| 3231 | 3231 | case L2F_WIN: |
| 3232 | 3232 | /* compute absolute physrec address */ |
| 3233 | | errorcode = win_fphysrec_to_aphysrec(&l2_file->u.win, fphysrec, &aphysrec); |
| 3233 | errorcode = win_fphysrec_to_aphysrec(&l2_file->win, fphysrec, &aphysrec); |
| 3234 | 3234 | if (errorcode) |
| 3235 | 3235 | return errorcode; |
| 3236 | 3236 | /* read physrec */ |
| 3237 | | if (read_absolute_physrec(& l2_file->u.win.l2_img->l1_img, aphysrec, dest)) |
| 3237 | if (read_absolute_physrec(& l2_file->win.l2_img->l1_img, aphysrec, dest)) |
| 3238 | 3238 | return IMGTOOLERR_READERROR; |
| 3239 | 3239 | break; |
| 3240 | 3240 | |
| 3241 | 3241 | case L2F_TIFILES: |
| 3242 | 3242 | /* seek to physrec */ |
| 3243 | | if (stream_seek(l2_file->u.tifiles.file_handle, 128+256*fphysrec, SEEK_SET)) |
| 3243 | if (stream_seek(l2_file->tifiles.file_handle, 128+256*fphysrec, SEEK_SET)) |
| 3244 | 3244 | return IMGTOOLERR_READERROR; |
| 3245 | 3245 | /* read it */ |
| 3246 | | if (stream_read(l2_file->u.tifiles.file_handle, dest, 256) != 256) |
| 3246 | if (stream_read(l2_file->tifiles.file_handle, dest, 256) != 256) |
| 3247 | 3247 | return IMGTOOLERR_READERROR; |
| 3248 | 3248 | break; |
| 3249 | 3249 | } |
| r17926 | r17927 | |
| 3254 | 3254 | /* |
| 3255 | 3255 | read a 256-byte physical record from a file |
| 3256 | 3256 | */ |
| 3257 | | static int write_file_physrec(ti99_lvl2_fileref *l2_file, unsigned fphysrec, const void *src) |
| 3257 | static int write_file_physrec(struct ti99_lvl2_fileref *l2_file, unsigned fphysrec, const void *src) |
| 3258 | 3258 | { |
| 3259 | 3259 | int errorcode; |
| 3260 | 3260 | unsigned aphysrec; |
| r17926 | r17927 | |
| 3263 | 3263 | { |
| 3264 | 3264 | case L2F_DSK: |
| 3265 | 3265 | /* compute absolute physrec address */ |
| 3266 | | errorcode = dsk_fphysrec_to_aphysrec(&l2_file->u.dsk, fphysrec, &aphysrec); |
| 3266 | errorcode = dsk_fphysrec_to_aphysrec(&l2_file->dsk, fphysrec, &aphysrec); |
| 3267 | 3267 | if (errorcode) |
| 3268 | 3268 | return errorcode; |
| 3269 | 3269 | /* write physrec */ |
| 3270 | | if (write_absolute_physrec(& l2_file->u.dsk.l2_img->l1_img, aphysrec, src)) |
| 3270 | if (write_absolute_physrec(& l2_file->dsk.l2_img->l1_img, aphysrec, src)) |
| 3271 | 3271 | return IMGTOOLERR_WRITEERROR; |
| 3272 | 3272 | break; |
| 3273 | 3273 | |
| 3274 | 3274 | case L2F_WIN: |
| 3275 | 3275 | /* compute absolute physrec address */ |
| 3276 | | errorcode = win_fphysrec_to_aphysrec(&l2_file->u.win, fphysrec, &aphysrec); |
| 3276 | errorcode = win_fphysrec_to_aphysrec(&l2_file->win, fphysrec, &aphysrec); |
| 3277 | 3277 | if (errorcode) |
| 3278 | 3278 | return errorcode; |
| 3279 | 3279 | /* write physrec */ |
| 3280 | | if (write_absolute_physrec(& l2_file->u.win.l2_img->l1_img, aphysrec, src)) |
| 3280 | if (write_absolute_physrec(& l2_file->win.l2_img->l1_img, aphysrec, src)) |
| 3281 | 3281 | return IMGTOOLERR_WRITEERROR; |
| 3282 | 3282 | break; |
| 3283 | 3283 | |
| 3284 | 3284 | case L2F_TIFILES: |
| 3285 | 3285 | /* seek to physrec */ |
| 3286 | | if (stream_seek(l2_file->u.tifiles.file_handle, 128+256*fphysrec, SEEK_SET)) |
| 3286 | if (stream_seek(l2_file->tifiles.file_handle, 128+256*fphysrec, SEEK_SET)) |
| 3287 | 3287 | return IMGTOOLERR_WRITEERROR; |
| 3288 | 3288 | /* write it */ |
| 3289 | | if (stream_write(l2_file->u.tifiles.file_handle, src, 256) != 256) |
| 3289 | if (stream_write(l2_file->tifiles.file_handle, src, 256) != 256) |
| 3290 | 3290 | return IMGTOOLERR_WRITEERROR; |
| 3291 | 3291 | break; |
| 3292 | 3292 | } |
| r17926 | r17927 | |
| 3298 | 3298 | Write a field in every fdr record associated to a file |
| 3299 | 3299 | */ |
| 3300 | 3300 | #ifdef UNUSED_FUNCTION |
| 3301 | | static int set_win_fdr_field(ti99_lvl2_fileref *l2_file, size_t offset, size_t size, void *data) |
| 3301 | static int set_win_fdr_field(struct ti99_lvl2_fileref *l2_file, size_t offset, size_t size, void *data) |
| 3302 | 3302 | { |
| 3303 | 3303 | win_fdr fdr_buf; |
| 3304 | 3304 | unsigned fdr_aphysrec; |
| 3305 | 3305 | int errorcode = 0; |
| 3306 | 3306 | |
| 3307 | | for (fdr_aphysrec = l2_file->u.win.eldestfdr_aphysrec; |
| 3308 | | fdr_aphysrec && ((errorcode = (read_absolute_physrec(&l2_file->u.win.l2_img->l1_img, fdr_aphysrec, &fdr_buf) ? IMGTOOLERR_READERROR : 0)) == 0); |
| 3309 | | fdr_aphysrec = get_win_fdr_nextsibFDR_physrec(l2_file->u.win.l2_img, &fdr_buf)) |
| 3307 | for (fdr_aphysrec = l2_file->win.eldestfdr_aphysrec; |
| 3308 | fdr_aphysrec && ((errorcode = (read_absolute_physrec(&l2_file->win.l2_img->l1_img, fdr_aphysrec, &fdr_buf) ? IMGTOOLERR_READERROR : 0)) == 0); |
| 3309 | fdr_aphysrec = get_win_fdr_nextsibFDR_physrec(l2_file->win.l2_img, &fdr_buf)) |
| 3310 | 3310 | { |
| 3311 | 3311 | memcpy(((UINT8 *) &fdr_buf) + offset, data, size); |
| 3312 | | if (write_absolute_physrec(&l2_file->u.win.l2_img->l1_img, fdr_aphysrec, &fdr_buf)) |
| 3312 | if (write_absolute_physrec(&l2_file->win.l2_img->l1_img, fdr_aphysrec, &fdr_buf)) |
| 3313 | 3313 | { |
| 3314 | 3314 | errorcode = IMGTOOLERR_WRITEERROR; |
| 3315 | 3315 | break; |
| r17926 | r17927 | |
| 3320 | 3320 | } |
| 3321 | 3321 | #endif |
| 3322 | 3322 | |
| 3323 | | static UINT8 get_file_flags(ti99_lvl2_fileref *l2_file) |
| 3323 | static UINT8 get_file_flags(struct ti99_lvl2_fileref *l2_file) |
| 3324 | 3324 | { |
| 3325 | 3325 | int reply = 0; |
| 3326 | 3326 | |
| 3327 | 3327 | switch (l2_file->type) |
| 3328 | 3328 | { |
| 3329 | 3329 | case L2F_DSK: |
| 3330 | | reply = l2_file->u.dsk.fdr.flags; |
| 3330 | reply = l2_file->dsk.fdr.flags; |
| 3331 | 3331 | break; |
| 3332 | 3332 | |
| 3333 | 3333 | case L2F_WIN: |
| 3334 | | reply = l2_file->u.win.curfdr.flags; |
| 3334 | reply = l2_file->win.curfdr.flags; |
| 3335 | 3335 | break; |
| 3336 | 3336 | |
| 3337 | 3337 | case L2F_TIFILES: |
| 3338 | | reply = l2_file->u.tifiles.hdr.flags; |
| 3338 | reply = l2_file->tifiles.hdr.flags; |
| 3339 | 3339 | break; |
| 3340 | 3340 | } |
| 3341 | 3341 | |
| 3342 | 3342 | return reply; |
| 3343 | 3343 | } |
| 3344 | 3344 | |
| 3345 | | static void set_file_flags(ti99_lvl2_fileref *l2_file, UINT8 data) |
| 3345 | static void set_file_flags(struct ti99_lvl2_fileref *l2_file, UINT8 data) |
| 3346 | 3346 | { |
| 3347 | 3347 | switch (l2_file->type) |
| 3348 | 3348 | { |
| 3349 | 3349 | case L2F_DSK: |
| 3350 | | l2_file->u.dsk.fdr.flags = data; |
| 3350 | l2_file->dsk.fdr.flags = data; |
| 3351 | 3351 | break; |
| 3352 | 3352 | |
| 3353 | 3353 | case L2F_WIN: |
| 3354 | | l2_file->u.win.curfdr.flags = data; |
| 3354 | l2_file->win.curfdr.flags = data; |
| 3355 | 3355 | break; |
| 3356 | 3356 | |
| 3357 | 3357 | case L2F_TIFILES: |
| 3358 | | l2_file->u.tifiles.hdr.flags = data; |
| 3358 | l2_file->tifiles.hdr.flags = data; |
| 3359 | 3359 | break; |
| 3360 | 3360 | } |
| 3361 | 3361 | } |
| 3362 | 3362 | |
| 3363 | | static UINT8 get_file_recsperphysrec(ti99_lvl2_fileref *l2_file) |
| 3363 | static UINT8 get_file_recsperphysrec(struct ti99_lvl2_fileref *l2_file) |
| 3364 | 3364 | { |
| 3365 | 3365 | int reply = 0; |
| 3366 | 3366 | |
| 3367 | 3367 | switch (l2_file->type) |
| 3368 | 3368 | { |
| 3369 | 3369 | case L2F_DSK: |
| 3370 | | reply = l2_file->u.dsk.fdr.recsperphysrec; |
| 3370 | reply = l2_file->dsk.fdr.recsperphysrec; |
| 3371 | 3371 | break; |
| 3372 | 3372 | |
| 3373 | 3373 | case L2F_WIN: |
| 3374 | | reply = l2_file->u.win.curfdr.recsperphysrec; |
| 3374 | reply = l2_file->win.curfdr.recsperphysrec; |
| 3375 | 3375 | break; |
| 3376 | 3376 | |
| 3377 | 3377 | case L2F_TIFILES: |
| 3378 | | reply = l2_file->u.tifiles.hdr.recsperphysrec; |
| 3378 | reply = l2_file->tifiles.hdr.recsperphysrec; |
| 3379 | 3379 | break; |
| 3380 | 3380 | } |
| 3381 | 3381 | |
| 3382 | 3382 | return reply; |
| 3383 | 3383 | } |
| 3384 | 3384 | |
| 3385 | | static void set_file_recsperphysrec(ti99_lvl2_fileref *l2_file, UINT8 data) |
| 3385 | static void set_file_recsperphysrec(struct ti99_lvl2_fileref *l2_file, UINT8 data) |
| 3386 | 3386 | { |
| 3387 | 3387 | switch (l2_file->type) |
| 3388 | 3388 | { |
| 3389 | 3389 | case L2F_DSK: |
| 3390 | | l2_file->u.dsk.fdr.recsperphysrec = data; |
| 3390 | l2_file->dsk.fdr.recsperphysrec = data; |
| 3391 | 3391 | break; |
| 3392 | 3392 | |
| 3393 | 3393 | case L2F_WIN: |
| 3394 | | l2_file->u.win.curfdr.recsperphysrec = data; |
| 3394 | l2_file->win.curfdr.recsperphysrec = data; |
| 3395 | 3395 | break; |
| 3396 | 3396 | |
| 3397 | 3397 | case L2F_TIFILES: |
| 3398 | | l2_file->u.tifiles.hdr.recsperphysrec = data; |
| 3398 | l2_file->tifiles.hdr.recsperphysrec = data; |
| 3399 | 3399 | break; |
| 3400 | 3400 | } |
| 3401 | 3401 | } |
| 3402 | 3402 | |
| 3403 | | static unsigned get_file_fphysrecs(ti99_lvl2_fileref *l2_file) |
| 3403 | static unsigned get_file_fphysrecs(struct ti99_lvl2_fileref *l2_file) |
| 3404 | 3404 | { |
| 3405 | 3405 | int reply = 0; |
| 3406 | 3406 | |
| 3407 | 3407 | switch (l2_file->type) |
| 3408 | 3408 | { |
| 3409 | 3409 | case L2F_DSK: |
| 3410 | | reply = get_UINT16BE(l2_file->u.dsk.fdr.fphysrecs); |
| 3410 | reply = get_UINT16BE(l2_file->dsk.fdr.fphysrecs); |
| 3411 | 3411 | break; |
| 3412 | 3412 | |
| 3413 | 3413 | case L2F_WIN: |
| 3414 | | reply = l2_file->u.win.fphysrecs; |
| 3414 | reply = l2_file->win.fphysrecs; |
| 3415 | 3415 | break; |
| 3416 | 3416 | |
| 3417 | 3417 | case L2F_TIFILES: |
| 3418 | | reply = get_UINT16BE(l2_file->u.tifiles.hdr.fphysrecs); |
| 3418 | reply = get_UINT16BE(l2_file->tifiles.hdr.fphysrecs); |
| 3419 | 3419 | break; |
| 3420 | 3420 | } |
| 3421 | 3421 | |
| 3422 | 3422 | return reply; |
| 3423 | 3423 | } |
| 3424 | 3424 | |
| 3425 | | static int set_file_fphysrecs(ti99_lvl2_fileref *l2_file, unsigned data) |
| 3425 | static int set_file_fphysrecs(struct ti99_lvl2_fileref *l2_file, unsigned data) |
| 3426 | 3426 | { |
| 3427 | 3427 | switch (l2_file->type) |
| 3428 | 3428 | { |
| 3429 | 3429 | case L2F_DSK: |
| 3430 | 3430 | if (data >= 65536) |
| 3431 | 3431 | return IMGTOOLERR_UNIMPLEMENTED; |
| 3432 | | set_UINT16BE(&l2_file->u.dsk.fdr.fphysrecs, data); |
| 3432 | set_UINT16BE(&l2_file->dsk.fdr.fphysrecs, data); |
| 3433 | 3433 | break; |
| 3434 | 3434 | |
| 3435 | 3435 | case L2F_WIN: |
| 3436 | | l2_file->u.win.fphysrecs = data; |
| 3436 | l2_file->win.fphysrecs = data; |
| 3437 | 3437 | break; |
| 3438 | 3438 | |
| 3439 | 3439 | case L2F_TIFILES: |
| 3440 | 3440 | if (data >= 65536) |
| 3441 | 3441 | return IMGTOOLERR_UNIMPLEMENTED; |
| 3442 | | set_UINT16BE(&l2_file->u.tifiles.hdr.fphysrecs, data); |
| 3442 | set_UINT16BE(&l2_file->tifiles.hdr.fphysrecs, data); |
| 3443 | 3443 | break; |
| 3444 | 3444 | } |
| 3445 | 3445 | |
| 3446 | 3446 | return 0; |
| 3447 | 3447 | } |
| 3448 | 3448 | |
| 3449 | | static UINT8 get_file_eof(ti99_lvl2_fileref *l2_file) |
| 3449 | static UINT8 get_file_eof(struct ti99_lvl2_fileref *l2_file) |
| 3450 | 3450 | { |
| 3451 | 3451 | int reply = 0; |
| 3452 | 3452 | |
| 3453 | 3453 | switch (l2_file->type) |
| 3454 | 3454 | { |
| 3455 | 3455 | case L2F_DSK: |
| 3456 | | reply = l2_file->u.dsk.fdr.eof; |
| 3456 | reply = l2_file->dsk.fdr.eof; |
| 3457 | 3457 | break; |
| 3458 | 3458 | |
| 3459 | 3459 | case L2F_WIN: |
| 3460 | | reply = l2_file->u.win.curfdr.eof; |
| 3460 | reply = l2_file->win.curfdr.eof; |
| 3461 | 3461 | break; |
| 3462 | 3462 | |
| 3463 | 3463 | case L2F_TIFILES: |
| 3464 | | reply = l2_file->u.tifiles.hdr.eof; |
| 3464 | reply = l2_file->tifiles.hdr.eof; |
| 3465 | 3465 | break; |
| 3466 | 3466 | } |
| 3467 | 3467 | |
| 3468 | 3468 | return reply; |
| 3469 | 3469 | } |
| 3470 | 3470 | |
| 3471 | | static void set_file_eof(ti99_lvl2_fileref *l2_file, UINT8 data) |
| 3471 | static void set_file_eof(struct ti99_lvl2_fileref *l2_file, UINT8 data) |
| 3472 | 3472 | { |
| 3473 | 3473 | switch (l2_file->type) |
| 3474 | 3474 | { |
| 3475 | 3475 | case L2F_DSK: |
| 3476 | | l2_file->u.dsk.fdr.eof = data; |
| 3476 | l2_file->dsk.fdr.eof = data; |
| 3477 | 3477 | break; |
| 3478 | 3478 | |
| 3479 | 3479 | case L2F_WIN: |
| 3480 | | l2_file->u.win.curfdr.eof = data; |
| 3480 | l2_file->win.curfdr.eof = data; |
| 3481 | 3481 | break; |
| 3482 | 3482 | |
| 3483 | 3483 | case L2F_TIFILES: |
| 3484 | | l2_file->u.tifiles.hdr.eof = data; |
| 3484 | l2_file->tifiles.hdr.eof = data; |
| 3485 | 3485 | break; |
| 3486 | 3486 | } |
| 3487 | 3487 | } |
| 3488 | 3488 | |
| 3489 | | static UINT16 get_file_reclen(ti99_lvl2_fileref *l2_file) |
| 3489 | static UINT16 get_file_reclen(struct ti99_lvl2_fileref *l2_file) |
| 3490 | 3490 | { |
| 3491 | 3491 | int reply = 0; |
| 3492 | 3492 | |
| 3493 | 3493 | switch (l2_file->type) |
| 3494 | 3494 | { |
| 3495 | 3495 | case L2F_DSK: |
| 3496 | | reply = l2_file->u.dsk.fdr.reclen; |
| 3497 | | if ((reply == 0) && (! (l2_file->u.dsk.fdr.flags & (fdr99_f_program /*| fdr99_f_var*/)))) |
| 3498 | | reply = get_UINT16BE(l2_file->u.dsk.fdr.xreclen); |
| 3496 | reply = l2_file->dsk.fdr.reclen; |
| 3497 | if ((reply == 0) && (! (l2_file->dsk.fdr.flags & (fdr99_f_program /*| fdr99_f_var*/)))) |
| 3498 | reply = get_UINT16BE(l2_file->dsk.fdr.xreclen); |
| 3499 | 3499 | break; |
| 3500 | 3500 | |
| 3501 | 3501 | case L2F_WIN: |
| 3502 | | reply = l2_file->u.win.curfdr.reclen; |
| 3503 | | if ((reply == 0) && (! (l2_file->u.win.curfdr.flags & (fdr99_f_program /*| fdr99_f_var*/)))) |
| 3504 | | reply = get_UINT16BE(l2_file->u.win.curfdr.xreclen); |
| 3502 | reply = l2_file->win.curfdr.reclen; |
| 3503 | if ((reply == 0) && (! (l2_file->win.curfdr.flags & (fdr99_f_program /*| fdr99_f_var*/)))) |
| 3504 | reply = get_UINT16BE(l2_file->win.curfdr.xreclen); |
| 3505 | 3505 | break; |
| 3506 | 3506 | |
| 3507 | 3507 | case L2F_TIFILES: |
| 3508 | | reply = l2_file->u.tifiles.hdr.reclen; |
| 3508 | reply = l2_file->tifiles.hdr.reclen; |
| 3509 | 3509 | break; |
| 3510 | 3510 | } |
| 3511 | 3511 | |
| 3512 | 3512 | return reply; |
| 3513 | 3513 | } |
| 3514 | 3514 | |
| 3515 | | static int set_file_reclen(ti99_lvl2_fileref *l2_file, UINT16 data) |
| 3515 | static int set_file_reclen(struct ti99_lvl2_fileref *l2_file, UINT16 data) |
| 3516 | 3516 | { |
| 3517 | 3517 | switch (l2_file->type) |
| 3518 | 3518 | { |
| 3519 | 3519 | case L2F_DSK: |
| 3520 | 3520 | if (data < 256) |
| 3521 | 3521 | { |
| 3522 | | l2_file->u.dsk.fdr.reclen = data; |
| 3523 | | set_UINT16BE(&l2_file->u.dsk.fdr.xreclen, 0); |
| 3522 | l2_file->dsk.fdr.reclen = data; |
| 3523 | set_UINT16BE(&l2_file->dsk.fdr.xreclen, 0); |
| 3524 | 3524 | } |
| 3525 | 3525 | else |
| 3526 | 3526 | { |
| 3527 | | l2_file->u.dsk.fdr.reclen = 0; |
| 3528 | | set_UINT16BE(&l2_file->u.dsk.fdr.xreclen, data); |
| 3527 | l2_file->dsk.fdr.reclen = 0; |
| 3528 | set_UINT16BE(&l2_file->dsk.fdr.xreclen, data); |
| 3529 | 3529 | } |
| 3530 | 3530 | break; |
| 3531 | 3531 | |
| 3532 | 3532 | case L2F_WIN: |
| 3533 | 3533 | if (data < 256) |
| 3534 | 3534 | { |
| 3535 | | l2_file->u.win.curfdr.reclen = data; |
| 3536 | | set_UINT16BE(&l2_file->u.win.curfdr.xreclen, 0); |
| 3535 | l2_file->win.curfdr.reclen = data; |
| 3536 | set_UINT16BE(&l2_file->win.curfdr.xreclen, 0); |
| 3537 | 3537 | } |
| 3538 | 3538 | else |
| 3539 | 3539 | { |
| 3540 | | l2_file->u.win.curfdr.reclen = 0; |
| 3541 | | set_UINT16BE(&l2_file->u.win.curfdr.xreclen, data); |
| 3540 | l2_file->win.curfdr.reclen = 0; |
| 3541 | set_UINT16BE(&l2_file->win.curfdr.xreclen, data); |
| 3542 | 3542 | } |
| 3543 | 3543 | break; |
| 3544 | 3544 | |
| 3545 | 3545 | case L2F_TIFILES: |
| 3546 | 3546 | if (data >= 256) |
| 3547 | 3547 | return IMGTOOLERR_UNIMPLEMENTED; |
| 3548 | | l2_file->u.tifiles.hdr.reclen = data; |
| 3548 | l2_file->tifiles.hdr.reclen = data; |
| 3549 | 3549 | break; |
| 3550 | 3550 | } |
| 3551 | 3551 | |
| 3552 | 3552 | return 0; |
| 3553 | 3553 | } |
| 3554 | 3554 | |
| 3555 | | static unsigned get_file_fixrecs(ti99_lvl2_fileref *l2_file) |
| 3555 | static unsigned get_file_fixrecs(struct ti99_lvl2_fileref *l2_file) |
| 3556 | 3556 | { |
| 3557 | 3557 | int reply = 0; |
| 3558 | 3558 | |
| 3559 | 3559 | switch (l2_file->type) |
| 3560 | 3560 | { |
| 3561 | 3561 | case L2F_DSK: |
| 3562 | | reply = get_UINT16LE(l2_file->u.dsk.fdr.fixrecs); |
| 3562 | reply = get_UINT16LE(l2_file->dsk.fdr.fixrecs); |
| 3563 | 3563 | break; |
| 3564 | 3564 | |
| 3565 | 3565 | case L2F_WIN: |
| 3566 | | reply = get_win_fdr_fixrecs(&l2_file->u.win.curfdr); |
| 3566 | reply = get_win_fdr_fixrecs(&l2_file->win.curfdr); |
| 3567 | 3567 | break; |
| 3568 | 3568 | |
| 3569 | 3569 | case L2F_TIFILES: |
| 3570 | | reply = get_UINT16BE(l2_file->u.tifiles.hdr.fixrecs); |
| 3570 | reply = get_UINT16BE(l2_file->tifiles.hdr.fixrecs); |
| 3571 | 3571 | break; |
| 3572 | 3572 | } |
| 3573 | 3573 | |
| 3574 | 3574 | return reply; |
| 3575 | 3575 | } |
| 3576 | 3576 | |
| 3577 | | static int set_file_fixrecs(ti99_lvl2_fileref *l2_file, unsigned data) |
| 3577 | static int set_file_fixrecs(struct ti99_lvl2_fileref *l2_file, unsigned data) |
| 3578 | 3578 | { |
| 3579 | 3579 | switch (l2_file->type) |
| 3580 | 3580 | { |
| 3581 | 3581 | case L2F_DSK: |
| 3582 | 3582 | if (data >= 65536) |
| 3583 | 3583 | return IMGTOOLERR_UNIMPLEMENTED; |
| 3584 | | set_UINT16LE(&l2_file->u.dsk.fdr.fixrecs, data); |
| 3584 | set_UINT16LE(&l2_file->dsk.fdr.fixrecs, data); |
| 3585 | 3585 | break; |
| 3586 | 3586 | |
| 3587 | 3587 | case L2F_WIN: |
| 3588 | | set_win_fdr_fixrecs(&l2_file->u.win.curfdr, data); |
| 3588 | set_win_fdr_fixrecs(&l2_file->win.curfdr, data); |
| 3589 | 3589 | break; |
| 3590 | 3590 | |
| 3591 | 3591 | case L2F_TIFILES: |
| 3592 | 3592 | if (data >= 65536) |
| 3593 | 3593 | return IMGTOOLERR_UNIMPLEMENTED; |
| 3594 | | set_UINT16BE(&l2_file->u.tifiles.hdr.fixrecs, data); |
| 3594 | set_UINT16BE(&l2_file->tifiles.hdr.fixrecs, data); |
| 3595 | 3595 | break; |
| 3596 | 3596 | } |
| 3597 | 3597 | |
| 3598 | 3598 | return 0; |
| 3599 | 3599 | } |
| 3600 | 3600 | |
| 3601 | | static void get_file_creation_date(ti99_lvl2_fileref *l2_file, ti99_date_time *reply) |
| 3601 | static void get_file_creation_date(struct ti99_lvl2_fileref *l2_file, ti99_date_time *reply) |
| 3602 | 3602 | { |
| 3603 | 3603 | switch (l2_file->type) |
| 3604 | 3604 | { |
| 3605 | 3605 | case L2F_DSK: |
| 3606 | | *reply = l2_file->u.dsk.fdr.creation; |
| 3606 | *reply = l2_file->dsk.fdr.creation; |
| 3607 | 3607 | break; |
| 3608 | 3608 | |
| 3609 | 3609 | case L2F_WIN: |
| 3610 | | *reply = l2_file->u.win.curfdr.creation; |
| 3610 | *reply = l2_file->win.curfdr.creation; |
| 3611 | 3611 | break; |
| 3612 | 3612 | |
| 3613 | 3613 | case L2F_TIFILES: |
| r17926 | r17927 | |
| 3616 | 3616 | } |
| 3617 | 3617 | } |
| 3618 | 3618 | |
| 3619 | | static void set_file_creation_date(ti99_lvl2_fileref *l2_file, ti99_date_time data) |
| 3619 | static void set_file_creation_date(struct ti99_lvl2_fileref *l2_file, ti99_date_time data) |
| 3620 | 3620 | { |
| 3621 | 3621 | switch (l2_file->type) |
| 3622 | 3622 | { |
| 3623 | 3623 | case L2F_DSK: |
| 3624 | | l2_file->u.dsk.fdr.creation = data; |
| 3624 | l2_file->dsk.fdr.creation = data; |
| 3625 | 3625 | break; |
| 3626 | 3626 | |
| 3627 | 3627 | case L2F_WIN: |
| 3628 | | l2_file->u.win.curfdr.creation = data; |
| 3628 | l2_file->win.curfdr.creation = data; |
| 3629 | 3629 | break; |
| 3630 | 3630 | |
| 3631 | 3631 | case L2F_TIFILES: |
| r17926 | r17927 | |
| 3633 | 3633 | } |
| 3634 | 3634 | } |
| 3635 | 3635 | |
| 3636 | | static void get_file_update_date(ti99_lvl2_fileref *l2_file, ti99_date_time *reply) |
| 3636 | static void get_file_update_date(struct ti99_lvl2_fileref *l2_file, ti99_date_time *reply) |
| 3637 | 3637 | { |
| 3638 | 3638 | switch (l2_file->type) |
| 3639 | 3639 | { |
| 3640 | 3640 | case L2F_DSK: |
| 3641 | | *reply = l2_file->u.dsk.fdr.update; |
| 3641 | *reply = l2_file->dsk.fdr.update; |
| 3642 | 3642 | break; |
| 3643 | 3643 | |
| 3644 | 3644 | case L2F_WIN: |
| 3645 | | *reply = l2_file->u.win.curfdr.update; |
| 3645 | *reply = l2_file->win.curfdr.update; |
| 3646 | 3646 | break; |
| 3647 | 3647 | |
| 3648 | 3648 | case L2F_TIFILES: |
| r17926 | r17927 | |
| 3651 | 3651 | } |
| 3652 | 3652 | } |
| 3653 | 3653 | |
| 3654 | | static void set_file_update_date(ti99_lvl2_fileref *l2_file, ti99_date_time data) |
| 3654 | static void set_file_update_date(struct ti99_lvl2_fileref *l2_file, ti99_date_time data) |
| 3655 | 3655 | { |
| 3656 | 3656 | switch (l2_file->type) |
| 3657 | 3657 | { |
| 3658 | 3658 | case L2F_DSK: |
| 3659 | | l2_file->u.dsk.fdr.update = data; |
| 3659 | l2_file->dsk.fdr.update = data; |
| 3660 | 3660 | break; |
| 3661 | 3661 | |
| 3662 | 3662 | case L2F_WIN: |
| 3663 | | l2_file->u.win.curfdr.update = data; |
| 3663 | l2_file->win.curfdr.update = data; |
| 3664 | 3664 | break; |
| 3665 | 3665 | |
| 3666 | 3666 | case L2F_TIFILES: |
| r17926 | r17927 | |
| 3829 | 3829 | */ |
| 3830 | 3830 | struct dsk_iterator |
| 3831 | 3831 | { |
| 3832 | | ti99_lvl2_imgref *image; |
| 3832 | struct ti99_lvl2_imgref *image; |
| 3833 | 3833 | int level; |
| 3834 | 3834 | int listing_subdirs; /* true if we are listing subdirectories at current level */ |
| 3835 | 3835 | int index[2]; /* current index in the disk catalog */ |
| r17926 | r17927 | |
| 3838 | 3838 | |
| 3839 | 3839 | struct win_iterator |
| 3840 | 3840 | { |
| 3841 | | ti99_lvl2_imgref *image; |
| 3841 | struct ti99_lvl2_imgref *image; |
| 3842 | 3842 | int level; |
| 3843 | 3843 | int listing_subdirs; /* true if we are listing subdirectories at current level */ |
| 3844 | 3844 | int index[MAX_DIR_LEVEL]; /* current index in the disk catalog */ |
| r17926 | r17927 | |
| 3995 | 3995 | */ |
| 3996 | 3996 | static int dsk_image_init(imgtool_image *img, imgtool_stream *f, ti99_img_format img_format) |
| 3997 | 3997 | { |
| 3998 | | ti99_lvl2_imgref *image = (ti99_lvl2_imgref *) imgtool_image_extra_bytes(img); |
| 3998 | struct ti99_lvl2_imgref *image = (struct ti99_lvl2_imgref *) imgtool_image_extra_bytes(img); |
| 3999 | 3999 | dsk_vib vib; |
| 4000 | 4000 | int reply; |
| 4001 | 4001 | int totphysrecs; |
| r17926 | r17927 | |
| 4024 | 4024 | image->AUformat.totAUs = totphysrecs / image->AUformat.physrecsperAU; |
| 4025 | 4025 | |
| 4026 | 4026 | /* extract number of physrecs */ |
| 4027 | | image->u.dsk.totphysrecs = get_UINT16BE(vib.totphysrecs); |
| 4027 | image->dsk.totphysrecs = get_UINT16BE(vib.totphysrecs); |
| 4028 | 4028 | |
| 4029 | 4029 | /* read and check main volume catalog */ |
| 4030 | | reply = dsk_read_catalog(image, 1, &image->u.dsk.catalogs[0]); |
| 4030 | reply = dsk_read_catalog(image, 1, &image->dsk.catalogs[0]); |
| 4031 | 4031 | if (reply) |
| 4032 | 4032 | return reply; |
| 4033 | 4033 | |
| 4034 | | image->u.dsk.fdir_aphysrec[0] = 1; |
| 4034 | image->dsk.fdir_aphysrec[0] = 1; |
| 4035 | 4035 | |
| 4036 | 4036 | /* read and check subdirectory catalogs */ |
| 4037 | 4037 | /* Note that the reserved areas used for HFDC subdirs may be used for other |
| 4038 | 4038 | purposes by other FDRs, so, if we get any error, we will assume there is no |
| 4039 | 4039 | subdir after all... */ |
| 4040 | | image->u.dsk.catalogs[0].num_subdirs = 0; |
| 4040 | image->dsk.catalogs[0].num_subdirs = 0; |
| 4041 | 4041 | for (i=0; i<3; i++) |
| 4042 | 4042 | { |
| 4043 | 4043 | fdir_aphysrec = get_UINT16BE(vib.subdir[i].fdir_aphysrec); |
| r17926 | r17927 | |
| 4047 | 4047 | /* name is empty: fine with us unless there is a fdir pointer */ |
| 4048 | 4048 | if (fdir_aphysrec != 0) |
| 4049 | 4049 | { |
| 4050 | | image->u.dsk.catalogs[0].num_subdirs = 0; |
| 4050 | image->dsk.catalogs[0].num_subdirs = 0; |
| 4051 | 4051 | break; |
| 4052 | 4052 | } |
| 4053 | 4053 | } |
| 4054 | 4054 | else if (check_fname(vib.subdir[i].name)) |
| 4055 | 4055 | { |
| 4056 | 4056 | /* name is invalid: this is not an HFDC format floppy */ |
| 4057 | | image->u.dsk.catalogs[0].num_subdirs = 0; |
| 4057 | image->dsk.catalogs[0].num_subdirs = 0; |
| 4058 | 4058 | break; |
| 4059 | 4059 | } |
| 4060 | 4060 | else |
| r17926 | r17927 | |
| 4063 | 4063 | if ((fdir_aphysrec == 0) || (fdir_aphysrec >= totphysrecs)) |
| 4064 | 4064 | { |
| 4065 | 4065 | /* error: fdir pointer is invalid or NULL */ |
| 4066 | | image->u.dsk.catalogs[0].num_subdirs = 0; |
| 4066 | image->dsk.catalogs[0].num_subdirs = 0; |
| 4067 | 4067 | break; |
| 4068 | 4068 | } |
| 4069 | 4069 | /* fill in descriptor fields */ |
| 4070 | | image->u.dsk.fdir_aphysrec[image->u.dsk.catalogs[0].num_subdirs+1] = fdir_aphysrec; |
| 4071 | | /*image->u.dsk.catalogs[0].subdirs[image->u.dsk.catalogs[0].num_subdirs].dir_ptr = fdir_aphysrec;*/ |
| 4072 | | memcpy(image->u.dsk.catalogs[0].subdirs[image->u.dsk.catalogs[0].num_subdirs].name, vib.subdir[i].name, 10); |
| 4073 | | reply = dsk_read_catalog(image, fdir_aphysrec, &image->u.dsk.catalogs[image->u.dsk.catalogs[0].num_subdirs+1]); |
| 4070 | image->dsk.fdir_aphysrec[image->dsk.catalogs[0].num_subdirs+1] = fdir_aphysrec; |
| 4071 | /*image->dsk.catalogs[0].subdirs[image->dsk.catalogs[0].num_subdirs].dir_ptr = fdir_aphysrec;*/ |
| 4072 | memcpy(image->dsk.catalogs[0].subdirs[image->dsk.catalogs[0].num_subdirs].name, vib.subdir[i].name, 10); |
| 4073 | reply = dsk_read_catalog(image, fdir_aphysrec, &image->dsk.catalogs[image->dsk.catalogs[0].num_subdirs+1]); |
| 4074 | 4074 | if (reply) |
| 4075 | 4075 | { |
| 4076 | 4076 | /* error: invalid fdir */ |
| 4077 | | image->u.dsk.catalogs[0].num_subdirs = 0; |
| 4077 | image->dsk.catalogs[0].num_subdirs = 0; |
| 4078 | 4078 | break; |
| 4079 | 4079 | } |
| 4080 | 4080 | /* found valid subdirectory: increment subdir count */ |
| 4081 | | image->u.dsk.catalogs[0].num_subdirs++; |
| 4081 | image->dsk.catalogs[0].num_subdirs++; |
| 4082 | 4082 | } |
| 4083 | 4083 | } |
| 4084 | 4084 | |
| r17926 | r17927 | |
| 4128 | 4128 | */ |
| 4129 | 4129 | static imgtoolerr_t win_image_init(imgtool_image *img, imgtool_stream *f) |
| 4130 | 4130 | { |
| 4131 | | ti99_lvl2_imgref *image = (ti99_lvl2_imgref *) imgtool_image_extra_bytes(img); |
| 4131 | struct ti99_lvl2_imgref *image = (struct ti99_lvl2_imgref *) imgtool_image_extra_bytes(img); |
| 4132 | 4132 | win_vib_ddr vib; |
| 4133 | 4133 | int reply; |
| 4134 | 4134 | int i; |
| r17926 | r17927 | |
| 4147 | 4147 | return (imgtoolerr_t)reply; |
| 4148 | 4148 | |
| 4149 | 4149 | /* guess VIB version */ |
| 4150 | | image->u.win.vib_version = memcmp(vib.u.vib_v1.id, "WIN", 3) ? win_vib_v2 : win_vib_v1; |
| 4150 | image->win.vib_version = memcmp(vib.u.vib_v1.id, "WIN", 3) ? win_vib_v2 : win_vib_v1; |
| 4151 | 4151 | |
| 4152 | 4152 | /* extract AU size and number of AUs */ |
| 4153 | 4153 | image->AUformat.physrecsperAU = ((get_UINT16BE(vib.params) >> 12) & 0xf) + 1; |
| r17926 | r17927 | |
| 4157 | 4157 | memcpy(image->vol_name, vib.name, 10); |
| 4158 | 4158 | |
| 4159 | 4159 | /* extract data_offset */ |
| 4160 | | switch (image->u.win.vib_version) |
| 4160 | switch (image->win.vib_version) |
| 4161 | 4161 | { |
| 4162 | 4162 | case win_vib_v1: |
| 4163 | 4163 | image->data_offset = 64; |
| r17926 | r17927 | |
| 4184 | 4184 | */ |
| 4185 | 4185 | static void ti99_image_exit(imgtool_image *img) |
| 4186 | 4186 | { |
| 4187 | | ti99_lvl2_imgref *image = (ti99_lvl2_imgref *) imgtool_image_extra_bytes(img); |
| 4187 | struct ti99_lvl2_imgref *image = (struct ti99_lvl2_imgref *) imgtool_image_extra_bytes(img); |
| 4188 | 4188 | |
| 4189 | 4189 | close_image_lvl1(&image->l1_img); |
| 4190 | 4190 | } |
| r17926 | r17927 | |
| 4196 | 4196 | */ |
| 4197 | 4197 | static void ti99_image_info(imgtool_image *img, char *string, size_t len) |
| 4198 | 4198 | { |
| 4199 | | ti99_lvl2_imgref *image = (ti99_lvl2_imgref *) imgtool_image_extra_bytes(img); |
| 4199 | struct ti99_lvl2_imgref *image = (struct ti99_lvl2_imgref *) imgtool_image_extra_bytes(img); |
| 4200 | 4200 | char vol_name[11]; |
| 4201 | 4201 | |
| 4202 | 4202 | fname_to_str(vol_name, image->vol_name, 11); |
| r17926 | r17927 | |
| 4209 | 4209 | */ |
| 4210 | 4210 | static imgtoolerr_t dsk_image_beginenum(imgtool_directory *enumeration, const char *path) |
| 4211 | 4211 | { |
| 4212 | | ti99_lvl2_imgref *image = (ti99_lvl2_imgref *) imgtool_image_extra_bytes(imgtool_directory_image(enumeration)); |
| 4212 | struct ti99_lvl2_imgref *image = (struct ti99_lvl2_imgref *) imgtool_image_extra_bytes(imgtool_directory_image(enumeration)); |
| 4213 | 4213 | dsk_iterator *iter = (dsk_iterator *) imgtool_directory_extrabytes(enumeration); |
| 4214 | 4214 | |
| 4215 | 4215 | iter->image = image; |
| 4216 | 4216 | iter->level = 0; |
| 4217 | 4217 | iter->listing_subdirs = 1; |
| 4218 | 4218 | iter->index[0] = 0; |
| 4219 | | iter->cur_catalog = &iter->image->u.dsk.catalogs[0]; |
| 4219 | iter->cur_catalog = &iter->image->dsk.catalogs[0]; |
| 4220 | 4220 | |
| 4221 | 4221 | return (imgtoolerr_t)0; |
| 4222 | 4222 | } |
| r17926 | r17927 | |
| 4255 | 4255 | { |
| 4256 | 4256 | iter->level = 0; |
| 4257 | 4257 | iter->index[0]++; |
| 4258 | | iter->cur_catalog = &iter->image->u.dsk.catalogs[0]; |
| 4258 | iter->cur_catalog = &iter->image->dsk.catalogs[0]; |
| 4259 | 4259 | } |
| 4260 | 4260 | } |
| 4261 | 4261 | } |
| r17926 | r17927 | |
| 4268 | 4268 | { |
| 4269 | 4269 | if (iter->listing_subdirs) |
| 4270 | 4270 | { |
| 4271 | | fname_to_str(ent->filename, iter->image->u.dsk.catalogs[0].subdirs[iter->index[iter->level]].name, ARRAY_LENGTH(ent->filename)); |
| 4271 | fname_to_str(ent->filename, iter->image->dsk.catalogs[0].subdirs[iter->index[iter->level]].name, ARRAY_LENGTH(ent->filename)); |
| 4272 | 4272 | |
| 4273 | 4273 | /* set type of DIR */ |
| 4274 | 4274 | snprintf(ent->attr, ARRAY_LENGTH(ent->attr), "DIR"); |
| r17926 | r17927 | |
| 4282 | 4282 | iter->listing_subdirs = 0; /* no need to list subdirs as only the |
| 4283 | 4283 | root dir has subdirs in DSK format */ |
| 4284 | 4284 | iter->level = 1; |
| 4285 | | iter->cur_catalog = &iter->image->u.dsk.catalogs[iter->index[0]+1]; |
| 4285 | iter->cur_catalog = &iter->image->dsk.catalogs[iter->index[0]+1]; |
| 4286 | 4286 | iter->index[iter->level] = 0; |
| 4287 | 4287 | } |
| 4288 | 4288 | else |
| r17926 | r17927 | |
| 4300 | 4300 | ent->filename[0] = '\0'; |
| 4301 | 4301 | if (iter->level) |
| 4302 | 4302 | { |
| 4303 | | fname_to_str(ent->filename, iter->image->u.dsk.catalogs[0].subdirs[iter->index[0]].name, ARRAY_LENGTH(ent->filename)); |
| 4303 | fname_to_str(ent->filename, iter->image->dsk.catalogs[0].subdirs[iter->index[0]].name, ARRAY_LENGTH(ent->filename)); |
| 4304 | 4304 | strncat(ent->filename, ".", ARRAY_LENGTH(ent->filename) - 1); |
| 4305 | 4305 | } |
| 4306 | 4306 | fname_to_str(buf, fdr.name, 11); |
| r17926 | r17927 | |
| 4334 | 4334 | */ |
| 4335 | 4335 | static imgtoolerr_t win_image_beginenum(imgtool_directory *enumeration, const char *path) |
| 4336 | 4336 | { |
| 4337 | | ti99_lvl2_imgref *image = (ti99_lvl2_imgref *) imgtool_image_extra_bytes(imgtool_directory_image(enumeration)); |
| 4337 | struct ti99_lvl2_imgref *image = (struct ti99_lvl2_imgref *) imgtool_image_extra_bytes(imgtool_directory_image(enumeration)); |
| 4338 | 4338 | win_iterator *iter = (win_iterator *) imgtool_directory_extrabytes(enumeration); |
| 4339 | 4339 | imgtoolerr_t errorcode; |
| 4340 | 4340 | |
| r17926 | r17927 | |
| 4479 | 4479 | static imgtoolerr_t ti99_image_freespace(imgtool_partition *partition, UINT64 *size) |
| 4480 | 4480 | { |
| 4481 | 4481 | imgtool_image *img = imgtool_partition_image(partition); |
| 4482 | | ti99_lvl2_imgref *image = (ti99_lvl2_imgref *) imgtool_image_extra_bytes(img); |
| 4482 | struct ti99_lvl2_imgref *image = (struct ti99_lvl2_imgref *) imgtool_image_extra_bytes(img); |
| 4483 | 4483 | size_t freeAUs; |
| 4484 | 4484 | int i; |
| 4485 | 4485 | |
| r17926 | r17927 | |
| 4506 | 4506 | #if 1 |
| 4507 | 4507 | |
| 4508 | 4508 | /* extract data as TIFILES */ |
| 4509 | | ti99_lvl2_imgref *image = (ti99_lvl2_imgref *) imgtool_image_extra_bytes(img); |
| 4509 | struct ti99_lvl2_imgref *image = (struct ti99_lvl2_imgref *) imgtool_image_extra_bytes(img); |
| 4510 | 4510 | ti99_lvl2_fileref src_file; |
| 4511 | 4511 | ti99_lvl2_fileref dst_file; |
| 4512 | 4512 | ti99_date_time date_time; |
| r17926 | r17927 | |
| 4572 | 4572 | #endif |
| 4573 | 4573 | set_file_update_date(&dst_file, date_time); |
| 4574 | 4574 | |
| 4575 | | if (stream_write(destf, & dst_file.u.tifiles.hdr, 128) != 128) |
| 4575 | if (stream_write(destf, & dst_file.tifiles.hdr, 128) != 128) |
| 4576 | 4576 | return (imgtoolerr_t)IMGTOOLERR_WRITEERROR; |
| 4577 | 4577 | |
| 4578 | 4578 | /* copy data to TIFILE */ |
| r17926 | r17927 | |
| 4593 | 4593 | |
| 4594 | 4594 | #else |
| 4595 | 4595 | |
| 4596 | | ti99_lvl2_imgref *image = (ti99_lvl2_imgref *) imgtool_image_extra_bytes(img); |
| 4596 | struct ti99_lvl2_imgref *image = (struct ti99_lvl2_imgref *) imgtool_image_extra_bytes(img); |
| 4597 | 4597 | ti99_lvl3_fileref src_file; |
| 4598 | 4598 | UINT8 buf[256]; |
| 4599 | 4599 | int reclen; |
| r17926 | r17927 | |
| 4645 | 4645 | static imgtoolerr_t ti99_image_writefile(imgtool_partition *partition, const char *fpath, const char *fork, imgtool_stream *sourcef, option_resolution *writeoptions) |
| 4646 | 4646 | { |
| 4647 | 4647 | imgtool_image *img = imgtool_partition_image(partition); |
| 4648 | | ti99_lvl2_imgref *image = (ti99_lvl2_imgref *) imgtool_image_extra_bytes(img); |
| 4648 | struct ti99_lvl2_imgref *image = (struct ti99_lvl2_imgref *) imgtool_image_extra_bytes(img); |
| 4649 | 4649 | const char *filename; |
| 4650 | 4650 | char ti_fname[10]; |
| 4651 | 4651 | ti99_lvl2_fileref src_file; |
| r17926 | r17927 | |
| 4746 | 4746 | switch (dst_file.type) |
| 4747 | 4747 | { |
| 4748 | 4748 | case L2F_DSK: |
| 4749 | | errorcode = (imgtoolerr_t)dsk_alloc_file_physrecs(&dst_file.u.dsk, fphysrecs); |
| 4749 | errorcode = (imgtoolerr_t)dsk_alloc_file_physrecs(&dst_file.dsk, fphysrecs); |
| 4750 | 4750 | if (errorcode) |
| 4751 | 4751 | return (imgtoolerr_t)errorcode; |
| 4752 | 4752 | break; |
| 4753 | 4753 | |
| 4754 | 4754 | case L2F_WIN: |
| 4755 | | errorcode = (imgtoolerr_t)win_alloc_file_physrecs(&dst_file.u.win, fphysrecs); |
| 4755 | errorcode = (imgtoolerr_t)win_alloc_file_physrecs(&dst_file.win, fphysrecs); |
| 4756 | 4756 | if (errorcode) |
| 4757 | 4757 | return (imgtoolerr_t)errorcode; |
| 4758 | 4758 | break; |
| r17926 | r17927 | |
| 4776 | 4776 | switch (image->type) |
| 4777 | 4777 | { |
| 4778 | 4778 | case L2I_DSK: |
| 4779 | | if (write_absolute_physrec(& image->l1_img, dst_file.u.dsk.fdr_aphysrec, &dst_file.u.dsk.fdr)) |
| 4779 | if (write_absolute_physrec(& image->l1_img, dst_file.dsk.fdr_aphysrec, &dst_file.dsk.fdr)) |
| 4780 | 4780 | return (imgtoolerr_t)IMGTOOLERR_WRITEERROR; |
| 4781 | 4781 | break; |
| 4782 | 4782 | |
| 4783 | 4783 | case L2I_WIN: |
| 4784 | 4784 | /* save fphysrecs field as well */ |
| 4785 | | if (dst_file.u.win.curfdr_aphysrec == dst_file.u.win.eldestfdr_aphysrec) |
| 4786 | | set_win_fdr_fphysrecs(&dst_file.u.win.curfdr, dst_file.u.win.fphysrecs); |
| 4787 | | if (write_absolute_physrec(& image->l1_img, dst_file.u.win.curfdr_aphysrec, &dst_file.u.win.curfdr)) |
| 4785 | if (dst_file.win.curfdr_aphysrec == dst_file.win.eldestfdr_aphysrec) |
| 4786 | set_win_fdr_fphysrecs(&dst_file.win.curfdr, dst_file.win.fphysrecs); |
| 4787 | if (write_absolute_physrec(& image->l1_img, dst_file.win.curfdr_aphysrec, &dst_file.win.curfdr)) |
| 4788 | 4788 | return (imgtoolerr_t)IMGTOOLERR_WRITEERROR; |
| 4789 | | if (dst_file.u.win.curfdr_aphysrec != dst_file.u.win.eldestfdr_aphysrec) |
| 4789 | if (dst_file.win.curfdr_aphysrec != dst_file.win.eldestfdr_aphysrec) |
| 4790 | 4790 | { |
| 4791 | | dst_file.u.win.curfdr_aphysrec = dst_file.u.win.eldestfdr_aphysrec; |
| 4792 | | if (read_absolute_physrec(& image->l1_img, dst_file.u.win.curfdr_aphysrec, &dst_file.u.win.curfdr)) |
| 4791 | dst_file.win.curfdr_aphysrec = dst_file.win.eldestfdr_aphysrec; |
| 4792 | if (read_absolute_physrec(& image->l1_img, dst_file.win.curfdr_aphysrec, &dst_file.win.curfdr)) |
| 4793 | 4793 | return (imgtoolerr_t)IMGTOOLERR_WRITEERROR; |
| 4794 | | set_win_fdr_fphysrecs(&dst_file.u.win.curfdr, dst_file.u.win.fphysrecs); |
| 4795 | | if (write_absolute_physrec(& image->l1_img, dst_file.u.win.curfdr_aphysrec, &dst_file.u.win.curfdr)) |
| 4794 | set_win_fdr_fphysrecs(&dst_file.win.curfdr, dst_file.win.fphysrecs); |
| 4795 | if (write_absolute_physrec(& image->l1_img, dst_file.win.curfdr_aphysrec, &dst_file.win.curfdr)) |
| 4796 | 4796 | return (imgtoolerr_t)IMGTOOLERR_WRITEERROR; |
| 4797 | 4797 | } |
| 4798 | 4798 | break; |
| r17926 | r17927 | |
| 4802 | 4802 | switch (image->type) |
| 4803 | 4803 | { |
| 4804 | 4804 | case L2I_DSK: |
| 4805 | | catalog = &image->u.dsk.catalogs[parent_ref]; |
| 4805 | catalog = &image->dsk.catalogs[parent_ref]; |
| 4806 | 4806 | for (i=0; i<128; i++) |
| 4807 | 4807 | { |
| 4808 | 4808 | buf[2*i] = catalog->files[i].fdr_ptr >> 8; |
| 4809 | 4809 | buf[2*i+1] = catalog->files[i].fdr_ptr & 0xff; |
| 4810 | 4810 | } |
| 4811 | | if (write_absolute_physrec(& image->l1_img, image->u.dsk.fdir_aphysrec[parent_ref], buf)) |
| 4811 | if (write_absolute_physrec(& image->l1_img, image->dsk.fdir_aphysrec[parent_ref], buf)) |
| 4812 | 4812 | return (imgtoolerr_t)IMGTOOLERR_WRITEERROR; |
| 4813 | 4813 | break; |
| 4814 | 4814 | |
| r17926 | r17927 | |
| 4871 | 4871 | static imgtoolerr_t dsk_image_deletefile(imgtool_partition *partition, const char *fpath) |
| 4872 | 4872 | { |
| 4873 | 4873 | imgtool_image *img = imgtool_partition_image(partition); |
| 4874 | | ti99_lvl2_imgref *image = (ti99_lvl2_imgref *) imgtool_image_extra_bytes(img); |
| 4874 | struct ti99_lvl2_imgref *image = (struct ti99_lvl2_imgref *) imgtool_image_extra_bytes(img); |
| 4875 | 4875 | dsk_fdr fdr; |
| 4876 | 4876 | int i, cluster_index; |
| 4877 | 4877 | unsigned cur_AU, cluster_lastfphysrec; |
| r17926 | r17927 | |
| 4891 | 4891 | |
| 4892 | 4892 | if (is_dir) |
| 4893 | 4893 | { |
| 4894 | | catalog = &image->u.dsk.catalogs[catalog_index+1]; |
| 4894 | catalog = &image->dsk.catalogs[catalog_index+1]; |
| 4895 | 4895 | |
| 4896 | 4896 | if ((catalog->num_files != 0) || (catalog->num_subdirs != 0)) |
| 4897 | 4897 | return IMGTOOLERR_UNIMPLEMENTED; |
| 4898 | 4898 | |
| 4899 | | catalog = &image->u.dsk.catalogs[0]; |
| 4899 | catalog = &image->dsk.catalogs[0]; |
| 4900 | 4900 | |
| 4901 | 4901 | /* free fdir AU */ |
| 4902 | | cur_AU = image->u.dsk.fdir_aphysrec[catalog_index+1] / image->AUformat.physrecsperAU; |
| 4902 | cur_AU = image->dsk.fdir_aphysrec[catalog_index+1] / image->AUformat.physrecsperAU; |
| 4903 | 4903 | image->abm[cur_AU >> 3] &= ~ (1 << (cur_AU & 7)); |
| 4904 | 4904 | |
| 4905 | 4905 | /* delete catalog entry */ |
| 4906 | 4906 | for (i=catalog_index; i<2; i++) |
| 4907 | 4907 | { |
| 4908 | 4908 | catalog->subdirs[i] = catalog->subdirs[i+1]; |
| 4909 | | image->u.dsk.fdir_aphysrec[i+1] = image->u.dsk.fdir_aphysrec[i+2]; |
| 4909 | image->dsk.fdir_aphysrec[i+1] = image->dsk.fdir_aphysrec[i+2]; |
| 4910 | 4910 | } |
| 4911 | 4911 | memset(catalog->subdirs[2].name, 0, 10); |
| 4912 | 4912 | catalog->subdirs[2].dir_ptr = 0; |
| 4913 | | image->u.dsk.fdir_aphysrec[3] = 0; |
| 4913 | image->dsk.fdir_aphysrec[3] = 0; |
| 4914 | 4914 | catalog->num_subdirs--; |
| 4915 | 4915 | |
| 4916 | 4916 | /* update directory and bitmap in vib */ |
| r17926 | r17927 | |
| 4923 | 4923 | for (i=0; i<3; i++) |
| 4924 | 4924 | { |
| 4925 | 4925 | memcpy(vib.subdir[i].name, catalog->subdirs[i].name, 10); |
| 4926 | | set_UINT16BE(&vib.subdir[i].fdir_aphysrec, image->u.dsk.fdir_aphysrec[i+1]); |
| 4926 | set_UINT16BE(&vib.subdir[i].fdir_aphysrec, image->dsk.fdir_aphysrec[i+1]); |
| 4927 | 4927 | } |
| 4928 | 4928 | |
| 4929 | 4929 | memcpy(vib.abm, image->abm, 200); |
| r17926 | r17927 | |
| 4934 | 4934 | } |
| 4935 | 4935 | else |
| 4936 | 4936 | { |
| 4937 | | catalog = &image->u.dsk.catalogs[parent_ref]; |
| 4937 | catalog = &image->dsk.catalogs[parent_ref]; |
| 4938 | 4938 | |
| 4939 | 4939 | if (read_absolute_physrec(& image->l1_img, catalog->files[catalog_index].fdr_ptr, &fdr)) |
| 4940 | 4940 | return IMGTOOLERR_READERROR; |
| r17926 | r17927 | |
| 4992 | 4992 | buf[2*i] = catalog->files[i].fdr_ptr >> 8; |
| 4993 | 4993 | buf[2*i+1] = catalog->files[i].fdr_ptr & 0xff; |
| 4994 | 4994 | } |
| 4995 | | if (write_absolute_physrec(& image->l1_img, image->u.dsk.fdir_aphysrec[parent_ref], buf)) |
| 4995 | if (write_absolute_physrec(& image->l1_img, image->dsk.fdir_aphysrec[parent_ref], buf)) |
| 4996 | 4996 | return IMGTOOLERR_WRITEERROR; |
| 4997 | 4997 | |
| 4998 | 4998 | /* update bitmap */ |
| r17926 | r17927 | |
| 5013 | 5013 | static imgtoolerr_t win_image_deletefile(imgtool_partition *partition, const char *fpath) |
| 5014 | 5014 | { |
| 5015 | 5015 | imgtool_image *img = imgtool_partition_image(partition); |
| 5016 | | ti99_lvl2_imgref *image = (ti99_lvl2_imgref *) imgtool_image_extra_bytes(img); |
| 5016 | struct ti99_lvl2_imgref *image = (struct ti99_lvl2_imgref *) imgtool_image_extra_bytes(img); |
| 5017 | 5017 | int parent_ddr_AU, is_dir, catalog_index; |
| 5018 | 5018 | win_fdr fdr; |
| 5019 | 5019 | int i; |