Rev 796 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
796 | DimkaM | 1 | #include "std.h" |
2 | |||
3 | #include "emul.h" |
||
4 | #include "vars.h" |
||
5 | #include "fdd.h" |
||
6 | #include "upd765.h" |
||
7 | |||
8 | #if 0 |
||
9 | #define dprintf printf |
||
10 | #else |
||
11 | #define dprintf(...) |
||
12 | #endif |
||
13 | |||
14 | #pragma pack(push, 1) |
||
15 | union TDiskInfo |
||
16 | { |
||
17 | struct |
||
18 | { |
||
19 | char Sig[34]; |
||
20 | char Name[14]; |
||
21 | u8 c; |
||
22 | u8 h; |
||
23 | u16 TrackSize; // ������ ��� dsk (�� ��� edsk) |
||
24 | u8 TrackOffsets[]; // c * h, ������ ��� edsk |
||
25 | }; |
||
26 | u8 Raw[256]; |
||
27 | }; |
||
28 | |||
29 | #ifndef __ICL // icl 19 ��� win �� ����� __builtin_offsetof |
||
30 | static_assert(offsetof(TDiskInfo, TrackOffsets) == 0x34); |
||
31 | #endif |
||
32 | |||
33 | struct TSecInfo |
||
34 | { |
||
35 | u8 c; |
||
36 | u8 h; |
||
37 | u8 r; |
||
38 | u8 n; // sector size code |
||
39 | u8 St1; |
||
40 | u8 St2; |
||
41 | u16 DataLen; // ������ ��� edsk |
||
42 | }; |
||
43 | |||
44 | union TTrackInfo |
||
45 | { |
||
46 | struct |
||
47 | { |
||
48 | char Sig[13]; |
||
49 | char Reserved[3]; |
||
50 | u8 c; |
||
51 | u8 h; |
||
52 | char Reserved2[2]; |
||
53 | u8 n; // sector size code |
||
54 | u8 NumSec; |
||
55 | u8 Gap3Len; |
||
56 | u8 Filler; |
||
57 | TSecInfo SecInfoList[]; |
||
58 | }; |
||
59 | u8 Raw[256]; |
||
60 | }; |
||
61 | #pragma pack(pop) |
||
62 | |||
63 | int FDD::read_dsk() |
||
64 | { |
||
65 | dprintf("read_dsk\n"); |
||
66 | |||
67 | const auto DiskInfo{ (const TDiskInfo *)snbuf }; |
||
68 | |||
69 | auto IsExtended{ memcmp(DiskInfo->Sig, "EXTENDED", 8) == 0}; |
||
70 | if(!IsExtended && memcmp(DiskInfo->Sig, "MV - CPC", 8) != 0) |
||
71 | { |
||
72 | return 0; |
||
73 | } |
||
74 | |||
75 | newdisk(DiskInfo->c, DiskInfo->h); |
||
76 | |||
77 | unsigned Offset{ sizeof(TDiskInfo) }; |
||
78 | for(unsigned c = 0; c < DiskInfo->c; c++) |
||
79 | { |
||
80 | for(unsigned h = 0; h < DiskInfo->h; h++) |
||
81 | { |
||
82 | auto TrkSize{ IsExtended ? unsigned(DiskInfo->TrackOffsets[c*DiskInfo->h + h] << 8U) : DiskInfo->TrackSize }; |
||
83 | if(TrkSize == 0) |
||
84 | { |
||
85 | continue; |
||
86 | } |
||
87 | t.seek(this, c, h, JUST_SEEK); |
||
88 | |||
89 | const auto TrackInfo{ (const TTrackInfo *)(snbuf + Offset) }; |
||
90 | const auto SecDataStart{ snbuf + Offset + sizeof(TTrackInfo) }; |
||
91 | auto SecData{ SecDataStart }; |
||
92 | u8* PrevSecData{ }; |
||
93 | |||
94 | bool IsOverlappedSec = false; // Capitan Blood, License to kill |
||
95 | if(IsExtended) |
||
96 | { |
||
97 | IsOverlappedSec = true; |
||
98 | constexpr unsigned SecLen[]{ 128, 256, 512, 1024, 2048, 4096, 6144 }; |
||
99 | for(unsigned s = 0; s < min(size_t(TrackInfo->NumSec), _countof(SecLen)); s++) |
||
100 | { |
||
101 | const auto &SecInfo{ TrackInfo->SecInfoList[s] }; |
||
102 | if(SecLen[s] != SecInfo.DataLen) |
||
103 | { |
||
104 | IsOverlappedSec = false; |
||
105 | break; |
||
106 | } |
||
107 | } |
||
108 | } |
||
109 | |||
110 | for(unsigned s = 0; s < TrackInfo->NumSec; s++) |
||
111 | { |
||
112 | const auto &SecInfo{ TrackInfo->SecInfoList[s] }; |
||
113 | auto SecInfoDataLen{ SecInfo.DataLen }; |
||
114 | t.hdr[s].c = SecInfo.c; |
||
115 | t.hdr[s].s = SecInfo.h; |
||
116 | t.hdr[s].n = SecInfo.r; |
||
117 | t.hdr[s].l = SecInfo.n; |
||
118 | t.hdr[s].c1 = 0; |
||
119 | t.hdr[s].c2 = 0; |
||
120 | t.hdr[s].wp = nullptr; |
||
121 | t.hdr[s].data = SecData; |
||
122 | |||
123 | |||
124 | t.hdr[s].datlen = IsExtended ? SecInfoDataLen : 128U << SecInfo.n; |
||
125 | if(t.hdr[s].datlen == 0) |
||
126 | { |
||
127 | t.hdr[s].data = nullptr; |
||
128 | } |
||
129 | |||
130 | // ������ ���� ��� � golden axe (������ ������ �� ����� (��� 6, ������ 8192) |
||
131 | // ��������� ������ �����, ������ ���� ������ �������) |
||
132 | // ���� ������ ������ �������� ������ ���������� � ���� ������� (��������� ������� ������������ � ���� ������ ����� �������) |
||
133 | // ����� ������� ���� ����� ��������� � udi ������� ����������� �������������� �� ������ A1A1A1 FE/FB |
||
134 | // � ���������� � ��������� � �������� �������� ����� �� �������� � dsk (��� ��� ���������� �������������� �� 2 ����) |
||
135 | // ������� � ������� �������, � ����� � ��������� �������� (������� ���������� �������� �������� �� ����� ��������) |
||
136 | /* |
||
137 | // ����� ������ ������ � ������� �� opera soft (�������� mot) |
||
138 | // ��������� ������ ����� (corsarios + mutant zone) |
||
139 | if(IsExtended && c == 40 && SecInfo.n == 8 && SecInfoDataLen == 0) |
||
140 | { |
||
141 | const auto &SecInfo{ TrackInfo->SecInfoList[s-1] }; |
||
142 | auto SecInfoDataLen{ SecInfo.DataLen }; |
||
143 | t.hdr[s].data = PrevSecData - 0x512; |
||
144 | t.hdr[s].datlen = IsExtended ? SecInfoDataLen : 128U << SecInfo.n; |
||
145 | } |
||
146 | */ |
||
147 | if((SecInfo.St1 & TUpd765::ST1_DE)) // crc error in address or data |
||
148 | { |
||
149 | if((SecInfo.St2 & TUpd765::ST2_DD)) // crc error in data |
||
150 | { |
||
151 | t.hdr[s].c2 = 2; |
||
152 | if(IsOverlappedSec) |
||
153 | { |
||
154 | t.hdr[s].data = nullptr; |
||
155 | } |
||
156 | } |
||
157 | else |
||
158 | { |
||
159 | t.hdr[s].c1 = 2; // crc error in address |
||
160 | // t.hdr[s].data = nullptr; |
||
161 | } |
||
162 | } |
||
163 | |||
164 | if(SecInfo.St2 & TUpd765::ST2_CM) |
||
165 | { |
||
166 | t.hdr[s].Flags = SECHDR::FL_DDAM; |
||
167 | } |
||
168 | else |
||
169 | { |
||
170 | t.hdr[s].Flags = 0; |
||
171 | } |
||
172 | PrevSecData = SecData; |
||
173 | SecData += IsExtended ? SecInfoDataLen : 128U << SecInfo.n; |
||
174 | } |
||
175 | t.s = TrackInfo->NumSec; |
||
176 | t.format(); |
||
177 | Offset += TrkSize; |
||
178 | } |
||
179 | } |
||
180 | return 1; |
||
181 | } |