summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/formats/ti99_dsk.h
blob: 64498f01a8e7f19f1b19b9ce561b4da2d25ee9bb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*********************************************************************

    formats/ti99_dsk.c

    TI99 and Geneve disk images

    Michael Zapf, Sept 2014

*********************************************************************/

#ifndef TI99_DSK_H
#define TI99_DSK_H

#include "flopimg.h"
#include "wd177x_dsk.h"

class ti99_floppy_format : public floppy_image_format_t
{
public:
	bool supports_save() const { return true; }
	bool load(io_generic *io, UINT32 form_factor, floppy_image *image);
	bool save(io_generic *io, floppy_image *image);

protected:
	int decode_bitstream(const UINT8 *bitstream, UINT8 *trackdata, int *sector, int cell_count, int encoding, UINT8 gapbytes, int track_size);
	UINT8 get_data_from_encoding(UINT16 raw);

	virtual int min_heads() =0;

	virtual void determine_sizes(io_generic *io, int& cell_size, int& sector_count, int& heads) =0;
	virtual int get_track_size(int cell_size, int sector_count) =0;
	virtual void load_track(io_generic *io, UINT8 *trackdata, int head, int track, int sectorcount, int trackcount, int cellsize) =0;
	virtual void write_track(io_generic *io, UINT8 *trackdata, int *sector, int track, int head, int maxsect, int maxtrack, int numbytes) =0;

	int get_encoding(int cell_size);
	int get_track_size(int cell_size);

	void generate_track_fm(int track, int head, int cell_size, UINT8* trackdata, floppy_image *image);
	void generate_track_mfm(int track, int head, int cell_size, UINT8* trackdata, floppy_image *image);

	bool check_for_address_marks(UINT8* trackdata, int encoding);

	// Debugging
	void showtrack(UINT8* trackdata, int length);
};

/*
    Modern implementation of the sector dump format.
*/
class ti99_sdf_format : public ti99_floppy_format
{
public:
	int identify(io_generic *io, UINT32 form_factor);
	const char *name() const;
	const char *description() const;
	const char *extensions() const;

private:
	void determine_sizes(io_generic *io, int& cell_size, int& sector_count, int& heads);
	int get_track_size(int cell_size, int sector_count);
	void write_track(io_generic *io, UINT8 *trackdata, int *sector, int track, int head, int maxsect, int maxtrack, int numbytes);
	void load_track(io_generic *io, UINT8 *trackdata, int head, int track, int sectorcount, int trackcount, int cellsize);

	// This format supports single-sided images
	int min_heads() { return 1; }

	struct ti99vib
	{
		char    name[10];       // volume name (10 characters, pad with spaces)
		UINT8   totsecsMSB;     // disk length in sectors (big-endian) (usually 360, 720 or 1440)
		UINT8   totsecsLSB;
		UINT8   secspertrack;   // sectors per track (usually 9 (FM) or 18 (MFM))
		UINT8   id[3];          // String "DSK"
		UINT8   protection;     // 'P' if disk is protected, ' ' otherwise.
		UINT8   tracksperside;  // tracks per side (usually 40)
		UINT8   sides;          // sides (1 or 2)
		UINT8   density;        // 0,1 (FM) or 2,3,4 (MFM)
		UINT8   res[36];        // Empty for traditional disks, or up to 3 directory pointers
		UINT8   abm[200];       // allocation bitmap: a 1 for each sector in use (sector 0 is LSBit of byte 0,
								// sector 7 is MSBit of byte 0, sector 8 is LSBit of byte 1, etc.)
	};
};

extern const floppy_format_type FLOPPY_TI99_SDF_FORMAT;

/*
    Modern implementation of the track dump format.
*/
class ti99_tdf_format : public ti99_floppy_format
{
public:
	int identify(io_generic *io, UINT32 form_factor);
	const char *name() const;
	const char *description() const;
	const char *extensions() const;

private:
	void determine_sizes(io_generic *io, int& cell_size, int& sector_count, int& heads);
	void load_track(io_generic *io, UINT8 *trackdata, int head, int track, int sectorcount, int trackcount, int cellsize);
	void write_track(io_generic *io, UINT8 *trackdata, int *sector, int track, int head, int maxsect, int maxtrack, int numbytes);
	int get_track_size(int cell_size, int sector_count);

	// This format only supports double-sided images
	int min_heads() { return 2; }
};

extern const floppy_format_type FLOPPY_TI99_TDF_FORMAT;

// ========================================================================
/*
    Legacy implementation.
*/

LEGACY_FLOPPY_OPTIONS_EXTERN(ti99);
void ti99_set_80_track_drives(int use80);

#endif /* TI99_DSK_H */