#pragma once
struct SECHDR
{
unsigned char c, s, n, l;
unsigned short crc; // CRC чруюыютър ёхъЄюЁр
// Їыруш crc чюэ√ рфЁхёр ш фрээ√ї:
// ╧Ёш ЇюЁьрЄшЁютрэшш:
// 0 - ухэхЁшЁєхЄё яЁртшы№эюх чэрўхэшх crc
// 1 - чряшё№ crc шч crc(фы рфЁхёр)/crcd(фы фрээ√ї)
// 2 - ю°шсюўэ√щ crc (ухэхЁшЁєхЄё шэтхЁёшхщ яЁртшы№эюую crc))
// ╧Ёш ўЄхэшш (ЇєэъЎш seek єёЄрэртыштрхЄ яюы c1 ш c2):
// 0 - ЁрёёўшЄрээюх crc эх ёютярфрхЄ ё єърчрээ√ь т чруюыютъх (тючтЁр∙рхЄё crc error)
// 1 - ЁрёёўшЄрээюх crc ёютярфрхЄ ё єърчрээ√ь т чруюыютъх
unsigned char c1, c2;
// ╙ърчрЄхы№ эр фрээ√х ёхъЄюЁр тэєЄЁш ЄЁ¤ър
// ╧Ёш ЇюЁьрЄшЁютрэшш ёяхшЎры№эюх чэрўхэшх:
// 1 -чряюыэ Є№ ёхъЄюЁ эєы ьш
u8 *data;
u8 *id; // ╙ърчрЄхы№ эр чруюыютюъ ёхъЄюЁр тэєЄЁш ЄЁ¤ър
u8 *wp; // ╙ърчрЄхы№ эр сшЄютє■ ърЁЄє ёсющэ√ї срщЄют ёхъЄюЁр тэєЄЁш ЄЁ¤ър (шёяюы№чєхЄё Єюы№ъю яЁш чруЁєчъх)
unsigned wp_start; // ═юьхЁ яхЁтюую сшЄр т ърЁЄх ёсющэ√ї срщЄют (юЄэюёшЄхы№эю эрўрыр ЄЁ¤ър) фы фрээюую ёхъЄюЁр
// ╨рчьхЁ ёхъЄюЁр т срщЄрї
// ╧Ёш ЇюЁьрЄшЁютрэшш:
// 0 - ╨рчьхЁ ёхъЄюЁр схЁхЄё ъръ (128 << n) & SectorSizeMask
unsigned datlen;
unsigned crcd; // used to load specific CRC from FDI-file
// ╚ёяюы№чє■Єё фы .dsk ЇюЁьрЄр
static constexpr u8 FL_DDAM{ 0b00000001 };
u8 Flags = 0;
};
enum SEEK_MODE
{
JUST_SEEK = 0, LOAD_SECTORS = 1
};
static inline bool test_bit(const u8 *data, unsigned bit)
{
return (data[bit >> 3] & (1U << (bit & 7))) != 0;
}
static inline void set_bit(u8 *data, unsigned bit)
{
data[bit >> 3] |= (1U << (bit & 7));
}
static inline void clr_bit(u8 *data, unsigned bit)
{
data[bit >> 3] &= ~(1U << (bit & 7));
}
struct TRKCACHE
{
// cached track position
struct FDD *drive;
unsigned cyl, side; // ╘шчшўхёъшх ярЁрьхЄЁ√
// generic track data
unsigned trklen;
// pointer to data inside UDI
u8 *trkd; // фрээ√х (ьюцхЄ с√Є№ NULL, хёыш ЄЁ¤ъ схч фрээ√ї)
u8 *trki; // сшЄютр ърЁЄр ёшэїЁюшьяєы№ёют
u8 *trkwp; // сшЄютр ърЁЄр ёсющэ√ї срщЄют
unsigned ts_byte; // cpu.t per byte
SEEK_MODE sf; // flag: is sectors filled
unsigned s; // no. of sectors
// sectors on track
SECHDR hdr[MAX_SEC];
void set_i(unsigned pos)
{
set_bit(trki, pos);
}
void clr_i(unsigned pos)
{
clr_bit(trki, pos);
}
bool test_i(unsigned pos)
{
return test_bit(trki, pos);
}
void set_wp(unsigned pos)
{
set_bit(trkwp, pos);
}
bool test_wp(unsigned pos)
{
return test_bit(trkwp, pos);
}
void write(unsigned pos, unsigned char byte, u8 index)
{
if(!trkd)
return;
trkd[pos] = byte;
if(index)
set_i(pos);
else
clr_i(pos);
}
void seek(FDD *d, unsigned cyl, unsigned side, SEEK_MODE fs);
void format(); // before use, call seek(d,c,s,JUST_SEEK), set s and hdr[]
unsigned write_sector(unsigned sec, unsigned l, unsigned char *data); // call seek(d,c,s,LOAD_SECTORS)
const SECHDR *get_sector(unsigned sec, unsigned l) const; // before use, call fill(d,c,s,LOAD_SECTORS)
void dump();
void clear()
{
drive = nullptr;
trkd = nullptr;
ts_byte = Z80FQ / (MAX_TRACK_LEN * FDD_RPS);
}
TRKCACHE()
{
clear();
}
};
struct FDD
{
u8 Id;
// drive data
__int64 motor; // 0 - not spinning, >0 - time when it'll stop
unsigned char track; // head position
// disk data
unsigned char *rawdata; // used in VirtualAlloc/VirtualFree
unsigned rawsize;
// ═рўры№эюх ўшёыю фюЁюцхъ (яЁш чруЁєчъх юсЁрчр шыш яЁш ёючфрэшш яєёЄюую фшёър), ьюцхЄ с√Є№ єтхышўхэю фю MAX_CYLS
// яєЄхь ЇюЁрЄшЁютрэш фюяюыэшЄхы№э√ї фюЁюцхъ єЄшышЄрьш Єшяр ADS ш яюфюсэ√ї
unsigned cyls;
unsigned sides;
unsigned trklen[MAX_CYLS][2];
u8 *trkd[MAX_CYLS][2]; // фрээ√х
u8 *trki[MAX_CYLS][2]; // сшЄют√х ърЁЄ√ ёшэїЁюшьяєы№ёют
u8 *trkwp[MAX_CYLS][2]; // сшЄют√х ърЁЄ√ ёсющэ√ї срщЄют
unsigned char optype; // bits: 0-not modified, 1-write sector, 2-format track
unsigned char snaptype;
TRKCACHE t; // used in read/write image
char name[0x200];
char dsc[0x200];
char test();
void free();
int index();
void format_trd(unsigned CylCnt); // ╚ёяюы№чєхЄё Єюы№ъю фы wldr_trd
void emptydisk(unsigned FreeSecCnt); // ╚ёяюы№чєхЄё Єюы№ъю фы wldr_trd
int addfile(unsigned char *hdr, unsigned char *data); // ╚ёяюы№чєхЄё Єюы№ъю фы wldr_trd
void addboot(); // ╚ёяюы№чєхЄё Єюы№ъю фы wldr_trd
void set_i(unsigned c, unsigned s, unsigned pos)
{
set_bit(trki[c][s], pos);
}
void newdisk(unsigned cyls, unsigned sides);
int read(unsigned char snType);
int read_scl();
int read_hob();
int read_trd();
int write_trd(FILE *ff);
int read_fdi();
int write_fdi(FILE *ff);
int read_td0();
int write_td0(FILE *ff);
int read_udi();
int write_udi(FILE *ff);
void format_isd();
int read_isd();
int write_isd(FILE *ff);
void format_pro();
int read_pro();
int write_pro(FILE *ff);
int read_dsk();
int read_ipf();
~FDD()
{
free();
}
};
bool done_fdd(bool Cancelable);