OSDN Git Service

c35606c7e263aa9b8ea1214f385564d1b93caac4
[csp-qt/common_source_project-fm7.git] / source / src / vm / harddisk.cpp
1 /*
2         Skelton for retropc emulator
3
4         Author : Takeda.Toshiya
5         Date   : 2006.09.16-
6
7         [ d88 handler ]
8 */
9
10 #include "harddisk.h"
11 #include "../fileio.h"
12
13 void HARDDISK::open(const _TCHAR* file_path, int default_sector_size)
14 {
15         uint8_t header[512];
16         pair_t tmp;
17         
18         close();
19         
20         if(FILEIO::IsFileExisting(file_path)) {
21                 fio = new FILEIO();
22                 
23                 if(fio->Fopen(file_path, FILEIO_READ_WRITE_BINARY)) {
24                         // from NP2 sxsihdd.c
25                         const char sig_vhd[8] = "VHD1.00";
26                         const char sig_nhd[15] = "T98HDDIMAGE.R0";
27                         
28                         fio->Fread(header, 256, 1);
29                         
30                         if(check_file_extension(file_path, _T(".thd"))) {
31                                 // T98
32 /*
33                                 typedef struct thd_header_s {
34                                         int16_t cylinders;
35                                 } thd_header_s;
36 */
37                                 header_size = 256;
38                                 tmp.read_2bytes_le_from(header + 0);
39                                 int cylinders = tmp.sd;
40                                 surfaces = 8;
41                                 int sectors = 33;
42                                 sector_size = 256;
43                                 sector_num = cylinders * surfaces * sectors;
44                         } else if(check_file_extension(file_path, _T(".nhd")) && memcmp(header, sig_nhd, 15) == 0) {
45                                 // T98Next
46 /*
47                                 typedef struct nhd_header_s {
48                                         char sig[16];
49                                         char comment[256];
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];
56                                 } nhd_header_t;
57 */
58                                 tmp.read_4bytes_le_from(header + 272);
59                                 header_size = tmp.sd;
60                                 tmp.read_4bytes_le_from(header + 276);
61                                 int cylinders = tmp.sd;
62                                 tmp.read_2bytes_le_from(header + 280);
63                                 surfaces = tmp.sd;
64                                 tmp.read_2bytes_le_from(header + 282);
65                                 int sectors = tmp.sd;
66                                 tmp.read_2bytes_le_from(header + 284);
67                                 sector_size = tmp.sd;
68                                 sector_num = cylinders * surfaces * sectors;
69                         } else if(check_file_extension(file_path, _T(".hdi"))) {
70                                 // ANEX86
71 /*
72                                 typedef struct hdi_header_s {
73                                         int32_t dummy;          // + 0
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
81                                 } hdi_header_t;
82 */
83                                 tmp.read_4bytes_le_from(header + 8);
84                                 header_size = tmp.sd;
85                                 tmp.read_4bytes_le_from(header + 16);
86                                 sector_size = tmp.sd;
87                                 tmp.read_4bytes_le_from(header + 20);
88                                 int sectors = tmp.sd;
89                                 tmp.read_4bytes_le_from(header + 24);
90                                 surfaces = tmp.sd;
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) {
95                                 // Virtual98
96 /*
97                                 typedef struct {
98                                         char    sig[3];         // +  0
99                                         char    ver[4];         // +  3
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;
111 */
112                                 header_size = 288;
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);
120                                 sector_num = tmp.sd;
121 //                              sector_num = cylinders * surfaces * sectors;
122                         } else {
123                                 // solid
124                                 header_size = 0;
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;
130                         }
131                 }
132         }
133 }
134
135 void HARDDISK::close()
136 {
137         // write disk image
138         if(fio != NULL) {
139                 if(fio->IsOpened()) {
140                         fio->Fclose();
141                 }
142                 delete fio;
143                 fio = NULL;
144         }
145 }
146
147 bool HARDDISK::mounted()
148 {
149         return (fio != NULL && fio->IsOpened());
150 }
151
152 bool HARDDISK::accessed()
153 {
154         bool value = access;
155         access = false;
156         return value;
157 }
158
159 bool HARDDISK::read_buffer(long position, int length, uint8_t *buffer)
160 {
161         if(mounted()) {
162                 if(fio->Fseek(header_size + position, FILEIO_SEEK_SET) == 0) {
163                         access = true;
164                         return (fio->Fread(buffer, length, 1) == 1);
165                 }
166         }
167         return false;
168 }
169
170 bool HARDDISK::write_buffer(long position, int length, uint8_t *buffer)
171 {
172         if(mounted()) {
173                 if(fio->Fseek(header_size + position, FILEIO_SEEK_SET) == 0) {
174                         access = true;
175                         return (fio->Fwrite(buffer, length, 1) == 1);
176                 }
177         }
178         return false;
179 }
180