summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/formats/d81_dsk.cpp
blob: a7f01c9c92e494160d61c255e8d13162f68c1017 (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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// license:BSD-3-Clause
// copyright-holders:Curt Coder
/*********************************************************************

    formats/d81_dsk.c

    Commodore 1581 disk image format

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

/*

PER TRACK ORGANIZATION:

    Hex 4E written as a gap, with 10 sectors of data, with full gaps written for motor speed variation.

PER SECTOR ORGANIZATION:

    MFM Encoding
    12 Bytes of Hex 00
    3 Bytes of Hex A1 (Data Hex A1, Clock Hex 0A)
    1 Byte of Hex FE (ID Address Mark)
    1 Byte (Track Number)
    1 Byte (Side Number)
    1 Byte (Sector Number)
    1 Byte (Sector Length, 02 for 512 Byte Sectors)
    2 Bytes CRC (Cyclic Redundancy Check)
    22 Bytes of Hex 22
    12 Bytes of Hex 00
    3 Bytes of Hex A1 (Data Hex A1, Clock Hex 0A)
    1 Byte of Hex FB (Data Address Mark)
    512 Bytes of Data
    2 Bytes of CRC (Cyclic Redundancy Check)
    38 Bytes of Hex 4E

 file offset       | CBM logical  |  drive physical   |   specials
 decimal sedecimal | track/sector | cyl head sec offs |
 ------------------+--------------+-------------------+--------------
       0 0x000000  |    01;00     |   00;01;01        | first block
     256 0x000100  |    01;01     |   00;01;01   +256 |
       .     .     |      .       |     .  .          |
    4864 0x001300  |    01;19     |   00;01;10   +256 |
    5120 0x001400  |    01;20     |   00;00;01        |
       .     .     |      .       |     .  .          |
    9984 0x002700  |    01;39     |   00;00;10   +256 |
   10240 0x002800  |    02;00     |   01;01;01        |
       .     .     |      .       |     .  .          |
   15360 0x003C00  |    02;20     |   01;00;01        |
       .     .     |      .       |     .  .          |
   20480 0x005000  |    03;00     |   02;01;01        |
       .     .     |      .       |     .  .          |
       .     .     |      .       |     .  .          |
   30729 0x007800  |    04;00     |   03;01;01        |
       .     .     |      .       |     .  .          |
       .     .     |      .       |     .  .          |
       .     .     |      .       |     .  .          |
  399360 0x061800  |    40;00     |   39;01;01        | disk header
  399616 0x061900  |    40;01     |   39;01;01   +256 | 1st BAM block
  399872 0x061A00  |    40;02     |   39;01;02        | 2nd BAM block
  400128 0x061B00  |    40;03     |   39;01;02   +256 | 1st dir block
       .     .     |      .       |     .  .          |
  409600 0x064000  |    41;00     |   40;01;01        |
       .     .     |      .       |     .  .          |
       .     .     |      .       |     .  .          |
       .     .     |      .       |     .  .          |
  808960 0x0C5800  |    80;00     |   79;01;01        |
       .     .     |      .       |     .  .          |
  813824 0x0C6B00  |    80;19     |   79;01;10   +256 |
  814080 0x0C6C00  |    80;20     |   79;00;01        |
       .     .     |      .       |     .  .          |
  818688 0x0C7E00  |    80;38     |   79;00;10        |
  818944 0x0C7F00  |    80;39     |   79;00;10   +256 | last block

*/

#include <cassert>

#include "formats/d81_dsk.h"

d81_format::d81_format() : wd177x_format(formats)
{
}

const char *d81_format::name() const
{
	return "d81";
}

const char *d81_format::description() const
{
	return "Commodore 1581 disk image";
}

const char *d81_format::extensions() const
{
	return "d81";
}

const d81_format::format d81_format::formats[] = {
	// track description
	// 32x4e 12x00 3xf5 fe 2x00 01 02 f7 22x4e 12x00 3xf5 fb 512x00 f7
	// 35x4e 12x00 3xf5 fe 2x00 02 02 f7 22x4e 12x00 3xf5 fb 512x00 f7
	// 35x4e 12x00 3xf5 fe 2x00 03 02 f7 22x4e 12x00 3xf5 fb 512x00 f7
	// 35x4e 12x00 3xf5 fe 2x00 04 02 f7 22x4e 12x00 3xf5 fb 512x00 f7
	// 35x4e 12x00 3xf5 fe 2x00 05 02 f7 22x4e 12x00 3xf5 fb 512x00 f7
	// 35x4e 12x00 3xf5 fe 2x00 06 02 f7 22x4e 12x00 3xf5 fb 512x00 f7
	// 35x4e 12x00 3xf5 fe 2x00 07 02 f7 22x4e 12x00 3xf5 fb 512x00 f7
	// 35x4e 12x00 3xf5 fe 2x00 08 02 f7 22x4e 12x00 3xf5 fb 512x00 f7
	// 35x4e 12x00 3xf5 fe 2x00 09 02 f7 22x4e 12x00 3xf5 fb 512x00 f7
	// 35x4e 12x00 3xf5 fe 2x00 0a 02 f7 22x4e 12x00 3xf5 fb 512x00 f7
	// 164x4e
	{
		floppy_image::FF_35, floppy_image::DSDD, floppy_image::MFM,
		2000, 10, 80, 2, 512, {}, 1, {}, 32, 22, 35
	},

	{}
};

floppy_image_format_t::desc_e* d81_format::get_desc_mfm(const format &f, int &current_size, int &end_gap_index)
{
	static floppy_image_format_t::desc_e desc[25] = {
	/* 00 */ { MFM, 0x4e, f.gap_1 },
	/* 01 */ { SECTOR_LOOP_START, 0, f.sector_count-1 },
	/* 02 */ {   MFM, 0x00, 12 },
	/* 03 */ {   CRC_CCITT_START, 1 },
	/* 04 */ {     RAW, 0x4489, 3 },
	/* 05 */ {     MFM, 0xfe, 1 },
	/* 06 */ {     TRACK_ID },
	/* 07 */ {     HEAD_ID_SWAP },
	/* 08 */ {     SECTOR_ID },
	/* 09 */ {     SIZE_ID },
	/* 10 */ {   CRC_END, 1 },
	/* 11 */ {   CRC, 1 },
	/* 12 */ {   MFM, 0x4e, f.gap_2 },
	/* 13 */ {   MFM, 0x00, 12 },
	/* 14 */ {   CRC_CCITT_START, 2 },
	/* 15 */ {     RAW, 0x4489, 3 },
	/* 16 */ {     MFM, 0xfb, 1 },
	/* 17 */ {     SECTOR_DATA, -1 },
	/* 18 */ {   CRC_END, 2 },
	/* 19 */ {   CRC, 2 },
	/* 20 */ {   MFM, 0x4e, f.gap_3 },
	/* 21 */ { SECTOR_LOOP_END },
	/* 22 */ { MFM, 0x4e, 0 },
	/* 23 */ { RAWBITS, 0x9254, 0 },
	/* 24 */ { END }
	};

	current_size = f.gap_1*16;
	if(f.sector_base_size)
	current_size += f.sector_base_size * f.sector_count * 16;
	else {
	for(int j=0; j != f.sector_count; j++)
		current_size += f.per_sector_size[j] * 16;
	}
	current_size += (12+3+1+4+2+f.gap_2+12+3+1+2+f.gap_3) * f.sector_count * 16;

	end_gap_index = 22;

	return desc;
}

const floppy_format_type FLOPPY_D81_FORMAT = &floppy_image_format_creator<d81_format>;