2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
11 #include "../fileio.h"
13 void HARDDISK::open(const _TCHAR* file_path, int default_sector_size)
20 if(FILEIO::IsFileExisting(file_path)) {
23 if(fio->Fopen(file_path, FILEIO_READ_WRITE_BINARY)) {
25 const char sig_vhd[8] = "VHD1.00";
26 const char sig_nhd[15] = "T98HDDIMAGE.R0";
28 fio->Fread(header, 256, 1);
30 if(check_file_extension(file_path, _T(".thd"))) {
33 typedef struct thd_header_s {
38 tmp.read_2bytes_le_from(header + 0);
39 int cylinders = tmp.sd;
43 sector_num = cylinders * surfaces * sectors;
44 } else if(check_file_extension(file_path, _T(".nhd")) && memcmp(header, sig_nhd, 15) == 0) {
47 typedef struct nhd_header_s {
50 int32_t header_size; // +272
51 int32_t cylinders; // +276
52 int16_t surfaces; // +280
53 int16_t sectors; // +282
54 int16_t sector_size; // +284
55 uint8_t reserved[0xe2];
58 tmp.read_4bytes_le_from(header + 272);
60 tmp.read_4bytes_le_from(header + 276);
61 int cylinders = tmp.sd;
62 tmp.read_2bytes_le_from(header + 280);
64 tmp.read_2bytes_le_from(header + 282);
66 tmp.read_2bytes_le_from(header + 284);
68 sector_num = cylinders * surfaces * sectors;
69 } else if(check_file_extension(file_path, _T(".hdi"))) {
72 typedef struct hdi_header_s {
74 int32_t hdd_type; // + 4
75 int32_t header_size; // + 8
76 int32_t hdd_size; // +12
77 int32_t sector_size; // +16
78 int32_t sectors; // +20
79 int32_t surfaces; // +24
80 int32_t cylinders; // +28
83 tmp.read_4bytes_le_from(header + 8);
85 tmp.read_4bytes_le_from(header + 16);
87 tmp.read_4bytes_le_from(header + 20);
89 tmp.read_4bytes_le_from(header + 24);
91 tmp.read_4bytes_le_from(header + 28);
92 int cylinders = tmp.sd;
93 sector_num = cylinders * surfaces * sectors;
94 } else if(check_file_extension(file_path, _T(".hdd")) && memcmp(header, sig_vhd, 5) == 0) {
100 char delimita; // + 7
101 char comment[128]; // + 8
102 uint8_t pad1[4]; // +136
103 int16_t mbsize; // +140
104 int16_t sectorsize; // +142
105 uint8_t sectors; // +144
106 uint8_t surfaces; // +145
107 int16_t cylinders; // +146
108 int32_t totals; // +148
109 uint8_t pad2[0x44]; // +152
110 } virtual98_header_t;
113 tmp.read_2bytes_le_from(header + 142);
114 sector_size = tmp.sd;
115 // int sectors = header[144];
116 surfaces = header[145];
117 // tmp.read_2bytes_le_from(header + 146);
118 // int cylinders = tmp.sd;
119 tmp.read_4bytes_le_from(header + 148);
121 // sector_num = cylinders * surfaces * sectors;
125 // sectors = 33, surfaces = 4, cylinders = 153, sector_size = 256 // 5MB
126 // sectors = 33, surfaces = 4, cylinders = 310, sector_size = 256 // 10MB
127 surfaces = (default_sector_size == 256 && fio->FileLength() <= 33 * 4 * 310 * 256) ? 4 : 8;
128 sector_size = default_sector_size;
129 sector_num = fio->FileLength() / sector_size;
135 void HARDDISK::close()
139 if(fio->IsOpened()) {
147 bool HARDDISK::mounted()
149 return (fio != NULL && fio->IsOpened());
152 bool HARDDISK::accessed()
159 bool HARDDISK::read_buffer(long position, int length, uint8_t *buffer)
162 if(fio->Fseek(header_size + position, FILEIO_SEEK_SET) == 0) {
164 return (fio->Fread(buffer, length, 1) == 1);
170 bool HARDDISK::write_buffer(long position, int length, uint8_t *buffer)
173 if(fio->Fseek(header_size + position, FILEIO_SEEK_SET) == 0) {
175 return (fio->Fwrite(buffer, length, 1) == 1);
182 #define STATE_VERSION 1
184 void HARDDISK::save_state(FILEIO* state_fio)
186 state_fio->FputUint32(STATE_VERSION);
188 state_fio->Fwrite(image_path, sizeof(image_path), 1);
190 uint8_t *buffer = (uint8_t *)malloc(0x100000); // 1MB
191 long remain = fio->FileLength();
192 state_fio->FputInt32(remain);
193 fio->Fseek(0, FILEIO_SEEK_SET);
195 long size = min(remain, 0x100000);
196 fio->Fread(buffer, size, 1);
197 state_fio->Fwrite(buffer, size, 1);
202 state_fio->FputInt32(0);
204 state_fio->FputInt32(header_size);
205 // state_fio->FputInt32(cylinders);
206 state_fio->FputInt32(surfaces);
207 // state_fio->FputInt32(sectors);
208 state_fio->FputInt32(sector_size);
209 state_fio->FputInt32(sector_num);
212 bool HARDDISK::load_state(FILEIO* state_fio)
216 if(state_fio->FgetUint32() != STATE_VERSION) {
219 state_fio->Fread(image_path, sizeof(image_path), 1);
220 long remain = state_fio->FgetInt32();
223 if(!fio->Fopen(image_path, FILEIO_READ_WRITE_NEW_BINARY)) {
224 if(check_file_extension(image_path, _T(".thd"))) {
225 create_local_path(image_path, _MAX_PATH, _T("temporary_saved_hard_disk_#%d.thd"), drive_num);
226 } else if(check_file_extension(image_path, _T(".nhd"))) {
227 create_local_path(image_path, _MAX_PATH, _T("temporary_saved_hard_disk_#%d.nhd"), drive_num);
228 } else if(check_file_extension(image_path, _T(".hdi"))) {
229 create_local_path(image_path, _MAX_PATH, _T("temporary_saved_hard_disk_#%d.hdi"), drive_num);
231 create_local_path(image_path, _MAX_PATH, _T("temporary_saved_hard_disk_#%d.dat"), drive_num);
233 fio->Fopen(image_path, FILEIO_READ_WRITE_NEW_BINARY);
235 if(fio->IsOpened()) {
236 uint8_t *buffer = (uint8_t *)malloc(0x100000); // 1MB
237 fio->Fseek(0, FILEIO_SEEK_SET);
239 long size = min(remain, 0x100000);
240 state_fio->Fread(buffer, size, 1);
241 fio->Fwrite(buffer, size, 1);
246 state_fio->Fseek(remain, FILEIO_SEEK_CUR);
249 header_size = state_fio->FgetInt32();
250 // cylinders = state_fio->FgetInt32();
251 surfaces = state_fio->FgetInt32();
252 // sectors = state_fio->FgetInt32();
253 sector_size = state_fio->FgetInt32();
254 sector_num = state_fio->FgetInt32();