PageRenderTime 66ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/disk.cpp

https://github.com/tonioni/WinUAE
C++ | 5979 lines | 5335 code | 459 blank | 185 comment | 1838 complexity | f4df4d55ceb951475eef724de372c779 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * UAE - The Un*x Amiga Emulator
  3. *
  4. * Floppy disk emulation
  5. *
  6. * Copyright 1995 Hannu Rummukainen
  7. * Copyright 1995-2001 Bernd Schmidt
  8. * Copyright 2000-2021 Toni Wilen
  9. *
  10. * Original High Density Drive Handling by Dr. Adil Temel (C) 2001 [atemel1@hotmail.com]
  11. *
  12. * Small modifications to support abstracted Floppy Disk "Bridges" to hardware, Copyright 2021 Robert Smith, https://amiga.robsmithdev.co.uk
  13. *
  14. */
  15. #include "sysconfig.h"
  16. #include "sysdeps.h"
  17. int disk_debug_logging = 0;
  18. int disk_debug_mode = 0;
  19. int disk_debug_track = -1;
  20. #define REVOLUTION_DEBUG 0
  21. #define MFM_VALIDATOR 0
  22. #include "uae.h"
  23. #include "options.h"
  24. #include "memory.h"
  25. #include "events.h"
  26. #include "custom.h"
  27. #include "disk.h"
  28. #include "gui.h"
  29. #include "zfile.h"
  30. #include "newcpu.h"
  31. #include "osemu.h"
  32. #include "execlib.h"
  33. #include "savestate.h"
  34. #include "cia.h"
  35. #include "debug.h"
  36. #ifdef FDI2RAW
  37. #include "fdi2raw.h"
  38. #endif
  39. #include "catweasel.h"
  40. #include "driveclick.h"
  41. #ifdef CAPS
  42. #include "caps/caps_win32.h"
  43. #endif
  44. #ifdef SCP
  45. #include "scp.h"
  46. #endif
  47. #include "crc32.h"
  48. #include "inputrecord.h"
  49. #include "amax.h"
  50. #ifdef RETROPLATFORM
  51. #include "rp.h"
  52. #endif
  53. #include "fsdb.h"
  54. #include "statusline.h"
  55. #include "rommgr.h"
  56. #include "tinyxml2.h"
  57. #ifdef FLOPPYBRIDGE
  58. #include "floppybridge/floppybridge_abstract.h"
  59. #include "floppybridge/floppybridge_lib.h"
  60. #endif
  61. #undef CATWEASEL
  62. int floppy_writemode = 0;
  63. /* support HD floppies */
  64. #define FLOPPY_DRIVE_HD
  65. /* Writable track length with normal 2us bitcell/300RPM motor, 12688 PAL, 12784 NTSC */
  66. /* DMA clock / (7 clocks per bit * 5 revs per second * 8 bits per byte) */
  67. #define FLOPPY_WRITE_LEN_PAL 12668 // 3546895 / (7 * 5 * 8)
  68. #define FLOPPY_WRITE_LEN_NTSC 12784 // 3579545 / (7 * 5 * 8)
  69. #define FLOPPY_WRITE_LEN (currprefs.floppy_write_length > 256 ? currprefs.floppy_write_length / 2 : (currprefs.ntscmode ? (FLOPPY_WRITE_LEN_NTSC / 2) : (FLOPPY_WRITE_LEN_PAL / 2)))
  70. #define FLOPPY_WRITE_MAXLEN 0x3800
  71. /* This works out to 350 PAL, 408 NTSC */
  72. #define FLOPPY_GAP_LEN (FLOPPY_WRITE_LEN - 11 * 544)
  73. /* 7 CCK per bit */
  74. #define NORMAL_FLOPPY_SPEED (7 * 256)
  75. /* max supported floppy drives, for small memory systems */
  76. #define MAX_FLOPPY_DRIVES 4
  77. #ifdef FLOPPY_DRIVE_HD
  78. #define DDHDMULT 2
  79. #else
  80. #define DDHDMULT 1
  81. #endif
  82. #define MAX_SECTORS (DDHDMULT * 11)
  83. #undef DEBUG_DRIVE_ID
  84. /* UAE-1ADF (ADF_EXT2)
  85. * W reserved
  86. * W number of tracks (default 2*80=160)
  87. *
  88. * W reserved
  89. * W type, 0=normal AmigaDOS track, 1 = raw MFM (upper byte = disk revolutions - 1)
  90. * L available space for track in bytes (must be even)
  91. * L track length in bits
  92. */
  93. static int side, direction, reserved_side;
  94. static uae_u8 selected = 15, disabled, reserved;
  95. static uae_u8 writebuffer[544 * MAX_SECTORS];
  96. static uae_u8 writesecheadbuffer[16 * MAX_SECTORS];
  97. #define DISK_INDEXSYNC 1
  98. #define DISK_WORDSYNC 2
  99. #define DISK_REVOLUTION 4 /* 8,16,32,64 */
  100. #define DSKREADY_UP_TIME 18
  101. #define DSKREADY_DOWN_TIME 24
  102. #define DSKDMA_OFF 0
  103. #define DSKDMA_INIT 1
  104. #define DSKDMA_READ 2
  105. #define DSKDMA_WRITE 3
  106. static int dskdmaen, dsklength, dsklength2, dsklen;
  107. static uae_u16 dskbytr_val;
  108. static uae_u32 dskpt;
  109. static bool fifo_filled;
  110. static uae_u16 fifo[3];
  111. static int fifo_inuse[3];
  112. static int dma_enable, bitoffset, syncoffset;
  113. static uae_u16 word, dsksync;
  114. static unsigned long dsksync_cycles;
  115. #define WORDSYNC_TIME 11
  116. /* Always carried through to the next line. */
  117. int disk_hpos;
  118. static int disk_jitter;
  119. static int indexdecay;
  120. static uae_u8 prev_data;
  121. static int prev_step;
  122. static bool initial_disk_statusline;
  123. static struct diskinfo disk_info_data = { 0 };
  124. static bool amax_enabled;
  125. typedef enum { TRACK_AMIGADOS, TRACK_RAW, TRACK_RAW1, TRACK_PCDOS, TRACK_DISKSPARE, TRACK_NONE } image_tracktype;
  126. typedef struct {
  127. uae_u16 len;
  128. int offs, extraoffs;
  129. int bitlen, track;
  130. uae_u16 sync;
  131. image_tracktype type;
  132. int revolutions;
  133. } trackid;
  134. #define MAX_TRACKS (2 * 83)
  135. /* We have three kinds of Amiga floppy drives
  136. * - internal A500/A2000 drive:
  137. * ID is always DRIVE_ID_NONE (S.T.A.G expects this)
  138. * - HD drive (A3000/A4000):
  139. * ID is DRIVE_ID_35DD if DD floppy is inserted or drive is empty
  140. * ID is DRIVE_ID_35HD if HD floppy is inserted
  141. * - regular external drive:
  142. * ID is always DRIVE_ID_35DD
  143. */
  144. #define DRIVE_ID_NONE 0x00000000
  145. #define DRIVE_ID_35DD 0xFFFFFFFF
  146. #define DRIVE_ID_35HD 0xAAAAAAAA
  147. #define DRIVE_ID_525SD 0x55555555 /* 40 track 5.25 drive , kickstart does not recognize this */
  148. typedef enum { ADF_NONE = -1, ADF_NORMAL, ADF_EXT1, ADF_EXT2, ADF_FDI, ADF_IPF, ADF_SCP, ADF_CATWEASEL, ADF_PCDOS, ADF_KICK, ADF_SKICK, ADF_NORMAL_HEADER, ADF_FLOPPYBRIDGE } drive_filetype;
  149. typedef struct {
  150. struct zfile *diskfile;
  151. struct zfile *writediskfile;
  152. struct zfile *pcdecodedfile;
  153. drive_filetype filetype;
  154. trackid trackdata[MAX_TRACKS];
  155. trackid writetrackdata[MAX_TRACKS];
  156. int buffered_cyl, buffered_side;
  157. int cyl;
  158. bool motoroff;
  159. int motordelay; /* dskrdy needs some clock cycles before it changes after switching off motor */
  160. bool state;
  161. int selected_delay;
  162. bool wrprot;
  163. bool forcedwrprot;
  164. uae_u16 bigmfmbuf[0x4000 * DDHDMULT];
  165. uae_u16 tracktiming[0x4000 * DDHDMULT];
  166. int multi_revolution;
  167. int revolution_check;
  168. int skipoffset;
  169. int mfmpos;
  170. int indexoffset;
  171. int tracklen;
  172. int revolutions;
  173. int prevtracklen;
  174. int trackspeed;
  175. int num_tracks, write_num_tracks, num_secs, num_heads;
  176. int hard_num_cyls;
  177. bool dskeject;
  178. bool dskchange;
  179. int dskchange_time;
  180. bool dskready;
  181. int dskready_up_time;
  182. int dskready_down_time;
  183. int writtento;
  184. int steplimit;
  185. frame_time_t steplimitcycle;
  186. int indexhack, indexhackmode;
  187. int ddhd; /* 1=DD 2=HD */
  188. int drive_id_scnt; /* drive id shift counter */
  189. int idbit;
  190. unsigned long drive_id; /* drive id to be reported */
  191. TCHAR newname[256]; /* storage space for new filename during eject delay */
  192. bool newnamewriteprotected;
  193. uae_u32 crc32;
  194. #ifdef FDI2RAW
  195. FDI *fdi;
  196. #endif
  197. int useturbo;
  198. int floppybitcounter; /* number of bits left */
  199. #ifdef CATWEASEL
  200. catweasel_drive *catweasel;
  201. #else
  202. int catweasel;
  203. int amax;
  204. int lastdataacesstrack;
  205. int lastrev;
  206. bool track_access_done;
  207. bool fourms;
  208. #endif
  209. #ifdef FLOPPYBRIDGE
  210. FloppyDiskBridge *bridge;
  211. bool writepending;
  212. #endif
  213. } drive;
  214. #define MIN_STEPLIMIT_CYCLE (CYCLE_UNIT * 140)
  215. static uae_u16 bigmfmbufw[0x4000 * DDHDMULT];
  216. static drive floppy[MAX_FLOPPY_DRIVES];
  217. static TCHAR dfxhistory[HISTORY_MAX][MAX_PREVIOUS_IMAGES][MAX_DPATH];
  218. static uae_u8 exeheader[]={0x00,0x00,0x03,0xf3,0x00,0x00,0x00,0x00};
  219. static uae_u8 bootblock_ofs[]={
  220. 0x44,0x4f,0x53,0x00,0xc0,0x20,0x0f,0x19,0x00,0x00,0x03,0x70,0x43,0xfa,0x00,0x18,
  221. 0x4e,0xae,0xff,0xa0,0x4a,0x80,0x67,0x0a,0x20,0x40,0x20,0x68,0x00,0x16,0x70,0x00,
  222. 0x4e,0x75,0x70,0xff,0x60,0xfa,0x64,0x6f,0x73,0x2e,0x6c,0x69,0x62,0x72,0x61,0x72,
  223. 0x79
  224. };
  225. static uae_u8 bootblock_ffs[]={
  226. 0x44, 0x4F, 0x53, 0x01, 0xE3, 0x3D, 0x0E, 0x72, 0x00, 0x00, 0x03, 0x70, 0x43, 0xFA, 0x00, 0x3E,
  227. 0x70, 0x25, 0x4E, 0xAE, 0xFD, 0xD8, 0x4A, 0x80, 0x67, 0x0C, 0x22, 0x40, 0x08, 0xE9, 0x00, 0x06,
  228. 0x00, 0x22, 0x4E, 0xAE, 0xFE, 0x62, 0x43, 0xFA, 0x00, 0x18, 0x4E, 0xAE, 0xFF, 0xA0, 0x4A, 0x80,
  229. 0x67, 0x0A, 0x20, 0x40, 0x20, 0x68, 0x00, 0x16, 0x70, 0x00, 0x4E, 0x75, 0x70, 0xFF, 0x4E, 0x75,
  230. 0x64, 0x6F, 0x73, 0x2E, 0x6C, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x00, 0x65, 0x78, 0x70, 0x61,
  231. 0x6E, 0x73, 0x69, 0x6F, 0x6E, 0x2E, 0x6C, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x00, 0x00, 0x00,
  232. };
  233. #define FS_OFS_DATABLOCKSIZE 488
  234. #define FS_FLOPPY_BLOCKSIZE 512
  235. #define FS_EXTENSION_BLOCKS 72
  236. #define FS_FLOPPY_TOTALBLOCKS 1760
  237. #define FS_FLOPPY_RESERVED 2
  238. static void writeimageblock (struct zfile *dst, uae_u8 *sector, int offset)
  239. {
  240. zfile_fseek (dst, offset, SEEK_SET);
  241. zfile_fwrite (sector, FS_FLOPPY_BLOCKSIZE, 1, dst);
  242. }
  243. static uae_u32 disk_checksum (uae_u8 *p, uae_u8 *c)
  244. {
  245. uae_u32 cs = 0;
  246. int i;
  247. for (i = 0; i < FS_FLOPPY_BLOCKSIZE; i+= 4)
  248. cs += (p[i] << 24) | (p[i+1] << 16) | (p[i+2] << 8) | (p[i+3] << 0);
  249. cs = (~cs) + 1;
  250. if (c) {
  251. c[0] = cs >> 24; c[1] = cs >> 16; c[2] = cs >> 8; c[3] = cs >> 0;
  252. }
  253. return cs;
  254. }
  255. static int dirhash (const uae_char *name)
  256. {
  257. unsigned long hash;
  258. int i;
  259. hash = strlen (name);
  260. for(i = 0; i < strlen (name); i++) {
  261. hash = hash * 13;
  262. hash = hash + toupper (name[i]);
  263. hash = hash & 0x7ff;
  264. }
  265. hash = hash % ((FS_FLOPPY_BLOCKSIZE / 4) - 56);
  266. return hash;
  267. }
  268. static void disk_date (uae_u8 *p)
  269. {
  270. static int pdays, pmins, pticks;
  271. int days, mins, ticks;
  272. struct timeval tv;
  273. struct mytimeval mtv;
  274. gettimeofday (&tv, NULL);
  275. tv.tv_sec -= _timezone;
  276. mtv.tv_sec = tv.tv_sec;
  277. mtv.tv_usec = tv.tv_usec;
  278. timeval_to_amiga (&mtv, &days, &mins, &ticks, 50);
  279. if (days == pdays && mins == pmins && ticks == pticks) {
  280. ticks++;
  281. if (ticks >= 50 * 60) {
  282. ticks = 0;
  283. mins++;
  284. if (mins >= 24 * 60)
  285. days++;
  286. }
  287. }
  288. pdays = days;
  289. pmins = mins;
  290. pticks = ticks;
  291. p[0] = days >> 24; p[1] = days >> 16; p[2] = days >> 8; p[3] = days >> 0;
  292. p[4] = mins >> 24; p[5] = mins >> 16; p[6] = mins >> 8; p[7] = mins >> 0;
  293. p[8] = ticks >> 24; p[9] = ticks >> 16; p[10] = ticks >> 8; p[11] = ticks >> 0;
  294. }
  295. static void createbootblock (uae_u8 *sector, int bootable, bool ffs)
  296. {
  297. memset (sector, 0, FS_FLOPPY_BLOCKSIZE);
  298. memcpy (sector, "DOS", 3);
  299. if (ffs) {
  300. sector[3] = 1;
  301. }
  302. if (bootable) {
  303. memcpy(sector + 8, bootblock_ofs + 8, sizeof(bootblock_ofs) - 8);
  304. uae_u32 crc = 0;
  305. for (int i = 0; i < FS_FLOPPY_BLOCKSIZE; i += 4) {
  306. uae_u32 v = (sector[i] << 24) | (sector[i + 1] << 16) | (sector[i + 2] << 8) | sector[i + 3];
  307. if (crc + v < crc) {
  308. crc++;
  309. }
  310. crc += v;
  311. }
  312. crc ^= 0xffffffff;
  313. sector[4] = crc >> 24;
  314. sector[5] = crc >> 16;
  315. sector[6] = crc >> 8;
  316. sector[7] = crc >> 0;
  317. }
  318. }
  319. static void createrootblock (uae_u8 *sector, const TCHAR *disk_name)
  320. {
  321. char *dn = ua (disk_name);
  322. if (strlen (dn) >= 30)
  323. dn[30] = 0;
  324. const char *dn2 = dn;
  325. if (dn2[0] == 0)
  326. dn2 = "empty";
  327. memset (sector, 0, FS_FLOPPY_BLOCKSIZE);
  328. sector[0+3] = 2;
  329. sector[12+3] = 0x48;
  330. sector[312] = sector[313] = sector[314] = sector[315] = (uae_u8)0xff;
  331. sector[316+2] = 881 >> 8; sector[316+3] = 881 & 255;
  332. sector[432] = (uae_u8)strlen (dn2);
  333. strcpy ((char*)sector + 433, dn2);
  334. sector[508 + 3] = 1;
  335. disk_date (sector + 420);
  336. memcpy (sector + 472, sector + 420, 3 * 4);
  337. memcpy (sector + 484, sector + 420, 3 * 4);
  338. xfree (dn);
  339. }
  340. static int getblock (uae_u8 *bitmap, int *prev)
  341. {
  342. int i = *prev;
  343. while (bitmap[i] != 0xff) {
  344. if (bitmap[i] == 0) {
  345. bitmap[i] = 1;
  346. *prev = i;
  347. return i;
  348. }
  349. i++;
  350. }
  351. i = 0;
  352. while (bitmap[i] != 0xff) {
  353. if (bitmap[i] == 0) {
  354. bitmap[i] = 1;
  355. *prev = i;
  356. return i;
  357. }
  358. i++;
  359. }
  360. return -1;
  361. }
  362. static void pl (uae_u8 *sector, int offset, uae_u32 v)
  363. {
  364. sector[offset + 0] = v >> 24;
  365. sector[offset + 1] = v >> 16;
  366. sector[offset + 2] = v >> 8;
  367. sector[offset + 3] = v >> 0;
  368. }
  369. static int createdirheaderblock (uae_u8 *sector, int parent, const char *filename, uae_u8 *bitmap, int *prevblock)
  370. {
  371. int block = getblock (bitmap, prevblock);
  372. memset (sector, 0, FS_FLOPPY_BLOCKSIZE);
  373. pl (sector, 0, 2);
  374. pl (sector, 4, block);
  375. disk_date (sector + 512 - 92);
  376. sector[512 - 80] = (uae_u8)strlen (filename);
  377. strcpy ((char*)sector + 512 - 79, filename);
  378. pl (sector, 512 - 12, parent);
  379. pl (sector, 512 - 4, 2);
  380. return block;
  381. }
  382. static int createfileheaderblock (struct zfile *z,uae_u8 *sector, int parent, const char *filename, struct zfile *src, uae_u8 *bitmap, bool ffs, int *prevblock)
  383. {
  384. uae_u8 sector2[FS_FLOPPY_BLOCKSIZE];
  385. uae_u8 sector3[FS_FLOPPY_BLOCKSIZE];
  386. int block = getblock (bitmap, prevblock);
  387. int datablock = getblock (bitmap, prevblock);
  388. int datasec = 1;
  389. int extensions;
  390. int extensionblock, extensioncounter, headerextension = 1;
  391. int size;
  392. int blocksize = ffs ? FS_FLOPPY_BLOCKSIZE : FS_OFS_DATABLOCKSIZE;
  393. zfile_fseek (src, 0, SEEK_END);
  394. size = (int)zfile_ftell (src);
  395. zfile_fseek (src, 0, SEEK_SET);
  396. extensions = (size + blocksize - 1) / blocksize;
  397. memset (sector, 0, FS_FLOPPY_BLOCKSIZE);
  398. pl (sector, 0, 2);
  399. pl (sector, 4, block);
  400. pl (sector, 8, extensions > FS_EXTENSION_BLOCKS ? FS_EXTENSION_BLOCKS : extensions);
  401. pl (sector, 16, datablock);
  402. pl (sector, FS_FLOPPY_BLOCKSIZE - 188, size);
  403. disk_date (sector + FS_FLOPPY_BLOCKSIZE - 92);
  404. sector[FS_FLOPPY_BLOCKSIZE - 80] = (uae_u8)strlen (filename);
  405. strcpy ((char*)sector + FS_FLOPPY_BLOCKSIZE - 79, filename);
  406. pl (sector, FS_FLOPPY_BLOCKSIZE - 12, parent);
  407. pl (sector, FS_FLOPPY_BLOCKSIZE - 4, -3);
  408. extensioncounter = 0;
  409. extensionblock = 0;
  410. while (size > 0) {
  411. int datablock2 = datablock;
  412. int extensionblock2 = extensionblock;
  413. if (extensioncounter == FS_EXTENSION_BLOCKS) {
  414. extensioncounter = 0;
  415. extensionblock = getblock (bitmap, prevblock);
  416. if (datasec > FS_EXTENSION_BLOCKS + 1) {
  417. pl (sector3, 8, FS_EXTENSION_BLOCKS);
  418. pl (sector3, FS_FLOPPY_BLOCKSIZE - 8, extensionblock);
  419. pl (sector3, 4, extensionblock2);
  420. disk_checksum(sector3, sector3 + 20);
  421. writeimageblock (z, sector3, extensionblock2 * FS_FLOPPY_BLOCKSIZE);
  422. } else {
  423. pl (sector, 512 - 8, extensionblock);
  424. }
  425. memset (sector3, 0, FS_FLOPPY_BLOCKSIZE);
  426. pl (sector3, 0, 16);
  427. pl (sector3, FS_FLOPPY_BLOCKSIZE - 12, block);
  428. pl (sector3, FS_FLOPPY_BLOCKSIZE - 4, -3);
  429. }
  430. memset (sector2, 0, FS_FLOPPY_BLOCKSIZE);
  431. if (!ffs) {
  432. pl(sector2, 0, 8);
  433. pl(sector2, 4, block);
  434. pl(sector2, 8, datasec);
  435. pl(sector2, 12, size > FS_OFS_DATABLOCKSIZE ? FS_OFS_DATABLOCKSIZE : size);
  436. zfile_fread(sector2 + 24, size > FS_OFS_DATABLOCKSIZE ? FS_OFS_DATABLOCKSIZE : size, 1, src);
  437. } else {
  438. zfile_fread(sector2, size > FS_FLOPPY_BLOCKSIZE ? FS_FLOPPY_BLOCKSIZE : size, 1, src);
  439. }
  440. datasec++;
  441. size -= blocksize;
  442. datablock = 0;
  443. if (size > 0) {
  444. datablock = getblock(bitmap, prevblock);
  445. }
  446. if (!ffs) {
  447. pl(sector2, 16, datablock);
  448. disk_checksum(sector2, sector2 + 20);
  449. }
  450. writeimageblock (z, sector2, datablock2 * FS_FLOPPY_BLOCKSIZE);
  451. if (datasec <= FS_EXTENSION_BLOCKS + 1)
  452. pl (sector, 512 - 204 - extensioncounter * 4, datablock2);
  453. else
  454. pl (sector3, 512 - 204 - extensioncounter * 4, datablock2);
  455. extensioncounter++;
  456. }
  457. if (datasec > FS_EXTENSION_BLOCKS) {
  458. pl (sector3, 8, extensioncounter);
  459. disk_checksum(sector3, sector3 + 20);
  460. writeimageblock (z, sector3, extensionblock * FS_FLOPPY_BLOCKSIZE);
  461. }
  462. disk_checksum(sector, sector + 20);
  463. writeimageblock (z, sector, block * FS_FLOPPY_BLOCKSIZE);
  464. return block;
  465. }
  466. static void createbitmapblock (uae_u8 *sector, uae_u8 *bitmap)
  467. {
  468. int i, j;
  469. memset (sector, 0, FS_FLOPPY_BLOCKSIZE);
  470. i = 0;
  471. for (;;) {
  472. uae_u32 mask = 0;
  473. for (j = 0; j < 32; j++) {
  474. if (bitmap[2 + i * 32 + j] == 0xff)
  475. break;
  476. if (!bitmap[2 + i * 32 + j])
  477. mask |= 1 << j;
  478. }
  479. sector[4 + i * 4 + 0] = mask >> 24;
  480. sector[4 + i * 4 + 1] = mask >> 16;
  481. sector[4 + i * 4 + 2] = mask >> 8;
  482. sector[4 + i * 4 + 3] = mask >> 0;
  483. if (bitmap[2 + i * 32 + j] == 0xff)
  484. break;
  485. i++;
  486. }
  487. disk_checksum(sector, sector + 0);
  488. }
  489. static int createimagefromexe(struct zfile *src, struct zfile *dst, int hd, bool ffs)
  490. {
  491. uae_u8 sector1[FS_FLOPPY_BLOCKSIZE], sector2[FS_FLOPPY_BLOCKSIZE];
  492. uae_u8 bitmap[FS_FLOPPY_TOTALBLOCKS * 2 + 8];
  493. int exesize;
  494. int blocksize = ffs ? FS_FLOPPY_BLOCKSIZE : FS_OFS_DATABLOCKSIZE;
  495. int blocks, extensionblocks;
  496. int totalblocks;
  497. int fblock1, dblock1;
  498. const char *fname1 = "runme.exe";
  499. const TCHAR *fname1b = _T("runme.adf");
  500. const char *fname2 = "startup-sequence";
  501. const char *dirname1 = "s";
  502. struct zfile *ss;
  503. int prevblock;
  504. memset (bitmap, 0, sizeof bitmap);
  505. zfile_fseek (src, 0, SEEK_END);
  506. exesize = (int)zfile_ftell (src);
  507. blocks = (exesize + blocksize - 1) / blocksize;
  508. extensionblocks = (blocks + FS_EXTENSION_BLOCKS - 1) / FS_EXTENSION_BLOCKS;
  509. /* bootblock=2, root=1, bitmap=1, startup-sequence=1+1, exefileheader=1 */
  510. totalblocks = 2 + 1 + 1 + 2 + 1 + blocks + extensionblocks;
  511. if (totalblocks > FS_FLOPPY_TOTALBLOCKS * hd)
  512. return 0;
  513. bitmap[880 * hd + 0] = 1;
  514. bitmap[880 * hd + 1] = 1;
  515. bitmap[0] = 1;
  516. bitmap[1] = 1;
  517. bitmap[1760 * hd] = -1;
  518. prevblock = 880 * hd;
  519. dblock1 = createdirheaderblock (sector2, 880 * hd, dirname1, bitmap, &prevblock);
  520. ss = zfile_fopen_empty (src, fname1b, strlen (fname1));
  521. zfile_fwrite (fname1, strlen(fname1), 1, ss);
  522. fblock1 = createfileheaderblock (dst, sector1, dblock1, fname2, ss, bitmap, ffs, &prevblock);
  523. zfile_fclose (ss);
  524. pl (sector2, 24 + dirhash (fname2) * 4, fblock1);
  525. disk_checksum(sector2, sector2 + 20);
  526. writeimageblock (dst, sector2, dblock1 * FS_FLOPPY_BLOCKSIZE);
  527. fblock1 = createfileheaderblock (dst, sector1, 880 * hd, fname1, src, bitmap, ffs, &prevblock);
  528. createrootblock (sector1, zfile_getfilename (src));
  529. pl (sector1, 24 + dirhash (fname1) * 4, fblock1);
  530. pl (sector1, 24 + dirhash (dirname1) * 4, dblock1);
  531. disk_checksum(sector1, sector1 + 20);
  532. writeimageblock (dst, sector1, 880 * hd * FS_FLOPPY_BLOCKSIZE);
  533. createbitmapblock (sector1, bitmap);
  534. writeimageblock (dst, sector1, (880 * hd + 1) * FS_FLOPPY_BLOCKSIZE);
  535. createbootblock (sector1, 1, ffs);
  536. writeimageblock (dst, sector1, 0 * FS_FLOPPY_BLOCKSIZE);
  537. return 1;
  538. }
  539. #ifdef FLOPPYBRIDGE
  540. static FloppyBridgeAPI *bridges[4];
  541. static int bridge_type[4];
  542. static const FloppyDiskBridge::BridgeDriver *bridge_driver[4];
  543. static FloppyBridgeAPI::BridgeInformation bridgeinfo;
  544. static int bridgeinfoloaded;
  545. static std::vector<FloppyBridgeAPI::DriverInformation> bridgedriverinfo;
  546. static void floppybridge_read_track(drive *drv);
  547. bool floppybridge_available;
  548. std::vector<FloppyBridgeAPI::FloppyBridgeProfileInformation> bridgeprofiles;
  549. static char *floppybridge_config = NULL;
  550. bool DISK_isfloppybridge(struct uae_prefs *p, int num)
  551. {
  552. return p->floppyslots[num].dfxtype == DRV_FB;
  553. }
  554. #endif
  555. static bool isfloppysound (drive *drv)
  556. {
  557. return drv->useturbo == 0;
  558. }
  559. static int get_floppy_speed (void)
  560. {
  561. int m = currprefs.floppy_speed;
  562. if (m <= 10)
  563. m = 100;
  564. m = NORMAL_FLOPPY_SPEED * 100 / m;
  565. return m;
  566. }
  567. static int get_floppy_speed_from_image(drive *drv)
  568. {
  569. int l, m;
  570. #ifdef FLOPPYBRIDGE
  571. if (drv->bridge) {
  572. drv->fourms = drv->bridge->getBitSpeed() == 4;
  573. m = NORMAL_FLOPPY_SPEED;
  574. if (drv->fourms) {
  575. m *= 2;
  576. }
  577. return m;
  578. }
  579. #endif
  580. m = get_floppy_speed();
  581. l = drv->tracklen;
  582. drv->fourms = false;
  583. if (!drv->tracktiming[0]) {
  584. m = m * l / (2 * 8 * FLOPPY_WRITE_LEN * drv->ddhd);
  585. }
  586. // 4us track?
  587. if (l < (FLOPPY_WRITE_LEN_PAL * 8) * 4 / 6) {
  588. m *= 2;
  589. drv->fourms = true;
  590. }
  591. if (m <= 0) {
  592. m = 1;
  593. }
  594. return m;
  595. }
  596. static const TCHAR *drive_id_name(drive *drv)
  597. {
  598. switch(drv->drive_id)
  599. {
  600. case DRIVE_ID_35HD : return _T("3.5HD");
  601. case DRIVE_ID_525SD: return _T("5.25SD");
  602. case DRIVE_ID_35DD : return _T("3.5DD");
  603. case DRIVE_ID_NONE : return _T("NONE");
  604. }
  605. return _T("UNKNOWN");
  606. }
  607. /* Simulate exact behaviour of an A3000T 3.5 HD disk drive.
  608. * The drive reports to be a 3.5 DD drive whenever there is no
  609. * disk or a 3.5 DD disk is inserted. Only 3.5 HD drive id is reported
  610. * when a real 3.5 HD disk is inserted. -Adil
  611. */
  612. static void drive_settype_id (drive *drv)
  613. {
  614. int drvnum = drv - &floppy[0];
  615. int t = currprefs.floppyslots[drvnum].dfxtype;
  616. #ifdef FLOPPYBRIDGE
  617. if (drv->bridge)
  618. {
  619. if (drv->bridge->isDiskInDrive()) {
  620. switch (drv->bridge->getDriveTypeID()) {
  621. case FloppyDiskBridge::DriveTypeID::dti35DD:
  622. drv->drive_id = DRIVE_ID_35DD;
  623. break;
  624. case FloppyDiskBridge::DriveTypeID::dti35HD:
  625. drv->drive_id = DRIVE_ID_35HD;
  626. break;
  627. case FloppyDiskBridge::DriveTypeID::dti5255SD:
  628. drv->drive_id = DRIVE_ID_525SD;
  629. break;
  630. }
  631. } else {
  632. drv->drive_id = DRIVE_ID_35DD;
  633. }
  634. drv->ddhd = drv->drive_id == DRIVE_ID_35HD ? 2 : 1;
  635. return;
  636. }
  637. #endif
  638. switch (t)
  639. {
  640. case DRV_35_HD:
  641. #ifdef FLOPPY_DRIVE_HD
  642. if (!drv->diskfile || drv->ddhd <= 1)
  643. drv->drive_id = DRIVE_ID_35DD;
  644. else
  645. drv->drive_id = DRIVE_ID_35HD;
  646. #else
  647. drv->drive_id = DRIVE_ID_35DD;
  648. #endif
  649. break;
  650. case DRV_35_DD_ESCOM:
  651. case DRV_35_DD:
  652. case DRV_525_DD:
  653. default:
  654. drv->drive_id = DRIVE_ID_35DD;
  655. break;
  656. case DRV_525_SD:
  657. drv->drive_id = DRIVE_ID_525SD;
  658. break;
  659. case DRV_NONE:
  660. case DRV_PC_525_ONLY_40:
  661. case DRV_PC_525_40_80:
  662. case DRV_PC_35_ONLY_80:
  663. drv->drive_id = DRIVE_ID_NONE;
  664. break;
  665. }
  666. #ifdef DEBUG_DRIVE_ID
  667. write_log (_T("drive_settype_id: DF%d: set to %s\n"), drv-floppy, drive_id_name(drv));
  668. #endif
  669. }
  670. static void drive_image_free (drive *drv)
  671. {
  672. switch (drv->filetype)
  673. {
  674. case ADF_IPF:
  675. #ifdef CAPS
  676. caps_unloadimage (drv - floppy);
  677. #endif
  678. break;
  679. case ADF_SCP:
  680. #ifdef SCP
  681. scp_close (drv - floppy);
  682. #endif
  683. break;
  684. case ADF_FDI:
  685. #ifdef FDI2RAW
  686. fdi2raw_header_free (drv->fdi);
  687. drv->fdi = 0;
  688. #endif
  689. break;
  690. }
  691. drv->filetype = ADF_NONE;
  692. zfile_fclose(drv->diskfile);
  693. drv->diskfile = NULL;
  694. zfile_fclose(drv->writediskfile);
  695. drv->writediskfile = NULL;
  696. zfile_fclose(drv->pcdecodedfile);
  697. drv->pcdecodedfile = NULL;
  698. }
  699. static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR *fname, bool fake, bool writeprotected);
  700. static void reset_drive_gui (int num)
  701. {
  702. struct gui_info_drive *gid = &gui_data.drives[num];
  703. gid->drive_disabled = 0;
  704. gid->df[0] = 0;
  705. gid->crc32 = 0;
  706. if (currprefs.floppyslots[num].dfxtype < 0)
  707. gid->drive_disabled = 1;
  708. }
  709. static void setamax (void)
  710. {
  711. #ifdef AMAX
  712. amax_enabled = false;
  713. if (is_device_rom(&currprefs, ROMTYPE_AMAX, 0) > 0) {
  714. /* Put A-Max as last drive in drive chain */
  715. int j;
  716. amax_enabled = true;
  717. for (j = 0; j < MAX_FLOPPY_DRIVES; j++)
  718. if (floppy[j].amax)
  719. return;
  720. for (j = 0; j < MAX_FLOPPY_DRIVES; j++) {
  721. if ((1 << j) & disabled) {
  722. floppy[j].amax = 1;
  723. write_log (_T("AMAX: drive %d\n"), j);
  724. return;
  725. }
  726. }
  727. }
  728. #endif
  729. }
  730. static bool ispcbridgedrive(int num)
  731. {
  732. int type = currprefs.floppyslots[num].dfxtype;
  733. return type == DRV_PC_525_ONLY_40 || type == DRV_PC_35_ONLY_80 || type == DRV_PC_525_40_80;
  734. }
  735. static bool drive_writeprotected(drive *drv)
  736. {
  737. #ifdef FLOPPYBRIDGE
  738. if (drv->bridge) {
  739. bool v = drv->bridge->isWriteProtected();
  740. return v;
  741. }
  742. #endif
  743. #ifdef CATWEASEL
  744. if (drv->catweasel)
  745. return 1;
  746. #endif
  747. return currprefs.floppy_read_only || drv->wrprot || drv->forcedwrprot || drv->diskfile == NULL;
  748. }
  749. static void reset_drive (int num)
  750. {
  751. drive *drv = &floppy[num];
  752. drv->amax = 0;
  753. drive_image_free (drv);
  754. drv->motoroff = 1;
  755. drv->idbit = 0;
  756. drv->drive_id = 0;
  757. drv->drive_id_scnt = 0;
  758. drv->lastdataacesstrack = -1;
  759. disabled &= ~(1 << num);
  760. reserved &= ~(1 << num);
  761. if (currprefs.floppyslots[num].dfxtype < 0 || ispcbridgedrive(num))
  762. disabled |= 1 << num;
  763. if (ispcbridgedrive(num))
  764. reserved |= 1 << num;
  765. reset_drive_gui (num);
  766. /* most internal Amiga floppy drives won't enable
  767. * diskready until motor is running at full speed
  768. * and next indexsync has been passed
  769. */
  770. drv->indexhackmode = 0;
  771. if (num == 0 && currprefs.floppyslots[num].dfxtype == 0)
  772. drv->indexhackmode = 1;
  773. drv->dskchange_time = 0;
  774. drv->dskchange = false;
  775. drv->dskready_down_time = 0;
  776. drv->dskready_up_time = 0;
  777. drv->buffered_cyl = -1;
  778. drv->buffered_side = -1;
  779. gui_led (num + LED_DF0, 0, -1);
  780. drive_settype_id (drv);
  781. _tcscpy (currprefs.floppyslots[num].df, changed_prefs.floppyslots[num].df);
  782. drv->newname[0] = 0;
  783. drv->newnamewriteprotected = false;
  784. #ifdef FLOPPYBRIDGE
  785. if (drv->bridge) {
  786. drv->bridge->resetDrive(drv->cyl);
  787. drv->indexhackmode = 0;
  788. drv->num_tracks = drv->bridge->getMaxCylinder() * 2;
  789. drv->filetype = ADF_FLOPPYBRIDGE;
  790. drv->tracklen = drv->bridge->maxMFMBitPosition();
  791. drv->ddhd = drv->bridge->getDriveTypeID() == FloppyDiskBridge::DriveTypeID::dti35HD ? 2 : 1;
  792. }
  793. #endif
  794. if (!drive_insert (drv, &currprefs, num, currprefs.floppyslots[num].df, false, false))
  795. disk_eject (num);
  796. }
  797. /* code for track display */
  798. static void update_drive_gui (int num, bool force)
  799. {
  800. drive *drv = floppy + num;
  801. bool writ = dskdmaen == DSKDMA_WRITE && drv->state && !((selected | disabled) & (1 << num));
  802. struct gui_info_drive *gid = &gui_data.drives[num];
  803. if (!force && drv->state == gid->drive_motor
  804. && drv->cyl == gid->drive_track
  805. && side == gui_data.drive_side
  806. && drv->crc32 == gid->crc32
  807. && writ == gid->drive_writing
  808. && drive_writeprotected(drv) == gid->floppy_protected
  809. && !_tcscmp (gid->df, currprefs.floppyslots[num].df))
  810. return;
  811. _tcscpy (gid->df, currprefs.floppyslots[num].df);
  812. gid->crc32 = drv->crc32;
  813. gid->drive_motor = drv->state;
  814. gid->drive_track = drv->cyl;
  815. if (reserved & (1 << num))
  816. gui_data.drive_side = reserved_side;
  817. else
  818. gui_data.drive_side = side;
  819. gid->drive_writing = writ;
  820. gid->floppy_protected = drive_writeprotected(drv);
  821. gid->floppy_inserted = gid->df[0] || (drv->bridge && !drv->bridge->hasDiskChanged());
  822. gui_led (num + LED_DF0, (gid->drive_motor ? 1 : 0) | (gid->drive_writing ? 2 : 0), -1);
  823. }
  824. static void drive_fill_bigbuf (drive * drv,int);
  825. void DISK_get_path_text(struct uae_prefs *p, int n, TCHAR *text)
  826. {
  827. _tcscpy(text, p->floppyslots[n].df);
  828. #ifdef FLOPPYBRIDGE
  829. if (DISK_isfloppybridge(p, n) && floppybridge_available) {
  830. if (!bridgeinfoloaded) {
  831. FloppyBridgeAPI::getBridgeDriverInformation(false, bridgeinfo);
  832. bridgeinfoloaded = 1;
  833. }
  834. _tcscpy(text, bridgeinfo.about);
  835. floppybridge_init(p);
  836. if (bridge_driver[n]) {
  837. _tcscat(text, _T(", "));
  838. TCHAR *name = au(bridge_driver[n]->name);
  839. TCHAR *man = au(bridge_driver[n]->manufacturer);
  840. _tcscat(text, name);
  841. _tcscat(text, _T(", "));
  842. _tcscat(text, man);
  843. xfree(man);
  844. xfree(name);
  845. }
  846. }
  847. #endif
  848. }
  849. int DISK_validate_filename (struct uae_prefs *p, const TCHAR *fname_in, int num, TCHAR *outfname, int leave_open, bool *wrprot, uae_u32 *crc32, struct zfile **zf)
  850. {
  851. TCHAR outname[MAX_DPATH];
  852. if (zf)
  853. *zf = NULL;
  854. if (crc32)
  855. *crc32 = 0;
  856. if (wrprot)
  857. *wrprot = p->floppy_read_only ? 1 : 0;
  858. if (outfname)
  859. outfname[0] = 0;
  860. #ifdef FLOPPYBRIDGE
  861. if (DISK_isfloppybridge(p, num)) {
  862. return 1;
  863. }
  864. #endif
  865. cfgfile_resolve_path_out_load(fname_in, outname, MAX_DPATH, PATH_FLOPPY);
  866. if (outfname)
  867. _tcscpy(outfname, outname);
  868. if (leave_open || !zf) {
  869. struct zfile *f = zfile_fopen (outname, _T("r+b"), ZFD_NORMAL | ZFD_DISKHISTORY);
  870. if (!f) {
  871. if (wrprot)
  872. *wrprot = 1;
  873. f = zfile_fopen (outname, _T("rb"), ZFD_NORMAL | ZFD_DISKHISTORY);
  874. }
  875. if (f && crc32)
  876. *crc32 = zfile_crc32 (f);
  877. if (!zf)
  878. zfile_fclose (f);
  879. else
  880. *zf = f;
  881. return f ? 1 : 0;
  882. } else {
  883. if (zfile_exists (outname)) {
  884. if (wrprot && !p->floppy_read_only)
  885. *wrprot = 0;
  886. if (crc32) {
  887. struct zfile *f = zfile_fopen (outname, _T("rb"), ZFD_NORMAL | ZFD_DISKHISTORY);
  888. if (f)
  889. *crc32 = zfile_crc32 (f);
  890. zfile_fclose (f);
  891. }
  892. return 1;
  893. } else {
  894. if (wrprot)
  895. *wrprot = 1;
  896. return 0;
  897. }
  898. }
  899. }
  900. static void updatemfmpos (drive *drv)
  901. {
  902. if (drv->prevtracklen) {
  903. drv->mfmpos = drv->mfmpos * (drv->tracklen * 1000 / drv->prevtracklen) / 1000;
  904. if (drv->mfmpos >= drv->tracklen)
  905. drv->mfmpos = drv->tracklen - 1;
  906. }
  907. drv->mfmpos %= drv->tracklen;
  908. drv->prevtracklen = drv->tracklen;
  909. }
  910. static void track_reset (drive *drv)
  911. {
  912. drv->tracklen = FLOPPY_WRITE_LEN * drv->ddhd * 2 * 8;
  913. drv->revolutions = 1;
  914. drv->trackspeed = get_floppy_speed ();
  915. drv->buffered_side = -1;
  916. drv->skipoffset = -1;
  917. drv->tracktiming[0] = 0;
  918. memset (drv->bigmfmbuf, 0xaa, FLOPPY_WRITE_LEN * 2 * drv->ddhd);
  919. updatemfmpos (drv);
  920. }
  921. static int read_header_ext2 (struct zfile *diskfile, trackid *trackdata, int *num_tracks, int *ddhd)
  922. {
  923. uae_u8 buffer[2 + 2 + 4 + 4];
  924. trackid *tid;
  925. int offs;
  926. int i;
  927. zfile_fseek (diskfile, 0, SEEK_SET);
  928. zfile_fread (buffer, 1, 8, diskfile);
  929. if (strncmp ((char*)buffer, "UAE-1ADF", 8))
  930. return 0;
  931. zfile_fread (buffer, 1, 4, diskfile);
  932. *num_tracks = buffer[2] * 256 + buffer[3];
  933. offs = 8 + 2 + 2 + (*num_tracks) * (2 + 2 + 4 + 4);
  934. for (i = 0; i < (*num_tracks); i++) {
  935. tid = trackdata + i;
  936. zfile_fread (buffer, 2 + 2 + 4 + 4, 1, diskfile);
  937. tid->type = (image_tracktype)buffer[3];
  938. tid->revolutions = buffer[2] + 1;
  939. tid->len = buffer[5] * 65536 + buffer[6] * 256 + buffer[7];
  940. tid->bitlen = buffer[9] * 65536 + buffer[10] * 256 + buffer[11];
  941. tid->offs = offs;
  942. if (tid->len > 20000 && ddhd)
  943. *ddhd = 2;
  944. tid->track = i;
  945. offs += tid->len;
  946. }
  947. return 1;
  948. }
  949. static void saveimagecutpathpart(TCHAR *name)
  950. {
  951. int i;
  952. i = _tcslen (name) - 1;
  953. while (i > 0) {
  954. if (name[i] == '/' || name[i] == '\\') {
  955. name[i] = 0;
  956. break;
  957. }
  958. if (name[i] == '.') {
  959. name[i] = 0;
  960. break;
  961. }
  962. i--;
  963. }
  964. while (i > 0) {
  965. if (name[i] == '/' || name[i] == '\\') {
  966. name[i] = 0;
  967. break;
  968. }
  969. i--;
  970. }
  971. }
  972. static void saveimagecutfilepart(TCHAR *name)
  973. {
  974. TCHAR tmp[MAX_DPATH];
  975. int i;
  976. _tcscpy(tmp, name);
  977. i = _tcslen (tmp) - 1;
  978. while (i > 0) {
  979. if (tmp[i] == '/' || tmp[i] == '\\') {
  980. _tcscpy(name, tmp + i + 1);
  981. break;
  982. }
  983. if (tmp[i] == '.') {
  984. tmp[i] = 0;
  985. break;
  986. }
  987. i--;
  988. }
  989. while (i > 0) {
  990. if (tmp[i] == '/' || tmp[i] == '\\') {
  991. _tcscpy(name, tmp + i + 1);
  992. break;
  993. }
  994. i--;
  995. }
  996. }
  997. static void saveimageaddfilename(TCHAR *dst, const TCHAR *src, int type)
  998. {
  999. _tcscat(dst, src);
  1000. if (type)
  1001. _tcscat(dst, _T(".save_adf"));
  1002. else
  1003. _tcscat(dst, _T("_save.adf"));
  1004. }
  1005. static TCHAR *DISK_get_default_saveimagepath (const TCHAR *name)
  1006. {
  1007. TCHAR name1[MAX_DPATH];
  1008. TCHAR path[MAX_DPATH];
  1009. _tcscpy(name1, name);
  1010. saveimagecutfilepart(name1);
  1011. fetch_saveimagepath (path, sizeof path / sizeof (TCHAR), 1);
  1012. saveimageaddfilename(path, name1, 0);
  1013. return my_strdup(path);
  1014. }
  1015. // -2 = existing, if not, use 0.
  1016. // -1 = as configured
  1017. // 0 = saveimages-dir
  1018. // 1 = image dir
  1019. TCHAR *DISK_get_saveimagepath(const TCHAR *name, int type)
  1020. {
  1021. int typev = type;
  1022. for (int i = 0; i < 2; i++) {
  1023. if (typev == 1 || (typev == -1 && saveimageoriginalpath) || (typev == -2 && (saveimageoriginalpath || i == 1))) {
  1024. TCHAR si_name[MAX_DPATH], si_path[MAX_DPATH];
  1025. _tcscpy(si_name, name);
  1026. _tcscpy(si_path, name);
  1027. saveimagecutfilepart(si_name);
  1028. saveimagecutpathpart(si_path);
  1029. _tcscat(si_path, FSDB_DIR_SEPARATOR_S);
  1030. saveimageaddfilename(si_path, si_name, 1);
  1031. if (typev != -2 || (typev == -2 && zfile_exists(si_path)))
  1032. return my_strdup(si_path);
  1033. }
  1034. if (typev == 2 || (typev == -1 && !saveimageoriginalpath) || (typev == -2 && (!saveimageoriginalpath || i == 1))) {
  1035. TCHAR *p = DISK_get_default_saveimagepath(name);
  1036. if (typev != -2 || (typev == -2 && zfile_exists(p)))
  1037. return p;
  1038. xfree(p);
  1039. }
  1040. }
  1041. return DISK_get_saveimagepath(name, -1);
  1042. }
  1043. static struct zfile *getexistingwritefile(struct uae_prefs *p, const TCHAR *name, int num, bool *wrprot)
  1044. {
  1045. struct zfile *zf = NULL;
  1046. TCHAR *path;
  1047. TCHAR outname[MAX_DPATH];
  1048. path = DISK_get_saveimagepath(name, saveimageoriginalpath);
  1049. DISK_validate_filename(p, path, num, outname, 1, wrprot, NULL, &zf);
  1050. xfree(path);
  1051. if (zf)
  1052. return zf;
  1053. path = DISK_get_saveimagepath(name, !saveimageoriginalpath);
  1054. DISK_validate_filename(p, path, num, outname, 1, wrprot, NULL, &zf);
  1055. xfree(path);
  1056. return zf;
  1057. }
  1058. static int iswritefileempty(struct uae_prefs *p, int num, const TCHAR *name)
  1059. {
  1060. struct zfile *zf;
  1061. bool wrprot;
  1062. uae_char buffer[8];
  1063. trackid td[MAX_TRACKS];
  1064. int tracks, ddhd, i, ret;
  1065. zf = getexistingwritefile(p, name, num, &wrprot);
  1066. if (!zf)
  1067. return 1;
  1068. zfile_fread (buffer, sizeof (char), 8, zf);
  1069. if (strncmp((uae_char*)buffer, "UAE-1ADF", 8)) {
  1070. zfile_fclose(zf);
  1071. return 0;
  1072. }
  1073. ret = read_header_ext2 (zf, td, &tracks, &ddhd);
  1074. zfile_fclose (zf);
  1075. if (!ret)
  1076. return 1;
  1077. for (i = 0; i < tracks; i++) {
  1078. if (td[i].bitlen)
  1079. return 0;
  1080. }
  1081. return 1;
  1082. }
  1083. static int openwritefile (struct uae_prefs *p, drive *drv, int create)
  1084. {
  1085. bool wrprot = 0;
  1086. drv->writediskfile = getexistingwritefile(p, currprefs.floppyslots[drv - &floppy[0]].df, drv - &floppy[0], &wrprot);
  1087. if (drv->writediskfile) {
  1088. drv->wrprot = wrprot;
  1089. if (!read_header_ext2 (drv->writediskfile, drv->writetrackdata, &drv->write_num_tracks, 0)) {
  1090. zfile_fclose (drv->writediskfile);
  1091. drv->writediskfile = 0;
  1092. drv->wrprot = 1;
  1093. } else {
  1094. if (drv->write_num_tracks > drv->num_tracks)
  1095. drv->num_tracks = drv->write_num_tracks;
  1096. }
  1097. } else if (zfile_iscompressed (drv->diskfile)) {
  1098. drv->wrprot = 1;
  1099. }
  1100. return drv->writediskfile ? 1 : 0;
  1101. }
  1102. static bool diskfile_iswriteprotect (struct uae_prefs *p, const TCHAR *fname_in, int num, int *needwritefile, drive_type *drvtype)
  1103. {
  1104. struct zfile *zf1, *zf2;
  1105. bool wrprot1 = 0, wrprot2 = 1;
  1106. uae_char buffer[25];
  1107. TCHAR outname[MAX_DPATH];
  1108. *needwritefile = 0;
  1109. *drvtype = DRV_35_DD;
  1110. DISK_validate_filename (p, fname_in, num, outname, 1, &wrprot1, NULL, &zf1);
  1111. if (!zf1)
  1112. return 1;
  1113. if (zfile_iscompressed (zf1)) {
  1114. wrprot1 = 1;
  1115. *needwritefile = 1;
  1116. }
  1117. zf2 = getexistingwritefile(p, fname_in, num, &wrprot2);
  1118. zfile_fclose (zf2);
  1119. zfile_fread (buffer, sizeof (char), 25, zf1);
  1120. zfile_fclose (zf1);
  1121. if (strncmp ((uae_char*) buffer, "CAPS", 4) == 0) {
  1122. *needwritefile = 1;
  1123. return wrprot2;
  1124. }
  1125. if (strncmp ((uae_char*) buffer, "SCP", 3) == 0) {
  1126. *needwritefile = 1;
  1127. return wrprot2;
  1128. }
  1129. if (strncmp ((uae_char*) buffer, "Formatted Disk Image file", 25) == 0) {
  1130. *needwritefile = 1;
  1131. return wrprot2;
  1132. }
  1133. if (strncmp ((uae_char*) buffer, "UAE-1ADF", 8) == 0) {
  1134. if (wrprot1)
  1135. return wrprot2;
  1136. return wrprot1;
  1137. }
  1138. if (strncmp ((uae_char*) buffer, "UAE--ADF", 8) == 0) {
  1139. *needwritefile = 1;
  1140. return wrprot2;
  1141. }
  1142. if (memcmp (exeheader, buffer, sizeof exeheader) == 0)
  1143. return 0;
  1144. if (wrprot1)
  1145. return wrprot2;
  1146. return wrprot1;
  1147. }
  1148. static bool isrecognizedext(const TCHAR *name)
  1149. {
  1150. const TCHAR *ext = _tcsrchr(name, '.');
  1151. if (ext) {
  1152. ext++;
  1153. if (!_tcsicmp(ext, _T("adf")) || !_tcsicmp(ext, _T("adz")) || !_tcsicmp(ext, _T("st")) ||
  1154. !_tcsicmp(ext, _T("ima")) || !_tcsicmp(ext, _T("img")) || !_tcsicmp(ext, _T("dsk")))
  1155. return true;
  1156. }
  1157. return false;
  1158. }
  1159. static void update_disk_statusline(int num)
  1160. {
  1161. drive *drv = &floppy[num];
  1162. #ifdef FLOPPYBRIDGE
  1163. if (drv->bridge) {
  1164. const char *name = drv->bridge->getDriverInfo()->name;
  1165. TCHAR *n = au(name);
  1166. statusline_add_message(STATUSTYPE_FLOPPY, _T("DF%d: %s"), num, n);
  1167. xfree(n);
  1168. return;
  1169. }
  1170. #endif
  1171. if (!drv->diskfile)
  1172. return;
  1173. const TCHAR *fname = zfile_getoriginalname(drv->diskfile);
  1174. if (!fname)
  1175. fname = zfile_getname(drv->diskfile);
  1176. if (!fname)
  1177. fname = _T("?");
  1178. if (disk_info_data.diskname[0])
  1179. statusline_add_message(STATUSTYPE_FLOPPY, _T("DF%d: [%s] %s"), num, disk_info_data.diskname, my_getfilepart(fname));
  1180. else
  1181. statusline_add_message(STATUSTYPE_FLOPPY, _T("DF%d: %s"), num, my_getfilepart(fname));
  1182. }
  1183. static int drive_insert (drive *drv, struct uae_prefs *p, int dnum, const TCHAR *fname_in, bool fake, bool forcedwriteprotect)
  1184. {
  1185. uae_u8 buffer[2 + 2 + 4 + 4];
  1186. trackid *tid;
  1187. int num_tracks, size;
  1188. int canauto;
  1189. TCHAR outname[MAX_DPATH];
  1190. int dfxtype = p->floppyslots[dnum].dfxtype;
  1191. drive_image_free (drv);
  1192. if (!fake && !drv->bridge) {
  1193. DISK_examine_image(p, dnum, &disk_info_data, false, NULL);
  1194. }
  1195. DISK_validate_filename (p, fname_in, dnum, outname, 1, &drv->wrprot, &drv->crc32, &drv->diskfile);
  1196. drv->forcedwrprot = forcedwriteprotect;
  1197. if (drv->forcedwrprot)
  1198. drv->wrprot = true;
  1199. drv->ddhd = 1;
  1200. drv->num_heads = 2;
  1201. drv->num_secs = 0;
  1202. drv->hard_num_cyls = dfxtype == DRV_525_SD ? 40 : 80;
  1203. drv->tracktiming[0] = 0;
  1204. drv->useturbo = 0;
  1205. drv->indexoffset = 0;
  1206. if (!fake) {
  1207. drv->dskeject = false;
  1208. gui_disk_image_change (dnum, outname, drv->wrprot);
  1209. }
  1210. if (!drv->motoroff) {
  1211. drv->dskready_up_time = DSKREADY_UP_TIME * 312 + (uaerand() & 511);
  1212. drv->dskready_down_time = 0;
  1213. }
  1214. if (drv->diskfile == NULL && !drv->catweasel && !drv->bridge) {
  1215. track_reset (drv);
  1216. return 0;
  1217. }
  1218. if (!fake) {
  1219. inprec_recorddiskchange (dnum, fname_in, drv->wrprot);
  1220. if (currprefs.floppyslots[dnum].df != fname_in) {
  1221. _tcsncpy (currprefs.floppyslots[dnum].df, fname_in, 255);
  1222. currprefs.floppyslots[dnum].df[255] = 0;
  1223. }
  1224. currprefs.floppyslots[dnum].forcedwriteprotect = forcedwriteprotect;
  1225. _tcsncpy (changed_prefs.floppyslots[dnum].df, fname_in, 255);
  1226. changed_prefs.floppyslots[dnum].df[255] = 0;
  1227. changed_prefs.floppyslots[dnum].forcedwriteprotect = forcedwriteprotect;
  1228. _tcscpy (drv->newname, fname_in);
  1229. drv->newnamewriteprotected = forcedwriteprotect;
  1230. gui_filename (dnum, outname);
  1231. }
  1232. memset (buffer, 0, sizeof buffer);
  1233. size = 0;
  1234. if (drv->diskfile) {
  1235. zfile_fread (buffer, sizeof (char), 8, drv->diskfile);
  1236. zfile_fseek (drv->diskfile, 0, SEEK_END);
  1237. size = (int)zfile_ftell (drv->diskfile);
  1238. zfile_fseek (drv->diskfile, 0, SEEK_SET);
  1239. }
  1240. canauto = 0;
  1241. if (isrecognizedext (outname))
  1242. canauto = 1;
  1243. if (!canauto && drv->diskfile && isrecognizedext (zfile_getname (drv->diskfile)))
  1244. canauto = 1;
  1245. // if PC-only drive, make sure PC-like floppies are always detected
  1246. if (!canauto && ispcbridgedrive(dnum))
  1247. canauto = 1;
  1248. if (drv->catweasel) {
  1249. drv->wrprot = true;
  1250. drv->filetype = ADF_CATWEASEL;
  1251. drv->num_tracks = 80;
  1252. drv->ddhd = 1;
  1253. #ifdef FLOPPYBRIDGE
  1254. } else if (drv->bridge) {
  1255. drv->ddhd = (drv->bridge->getDriveTypeID() == FloppyDiskBridge::DriveTypeID::dti35HD) ? 2 : 1;
  1256. drv->num_heads = 2;
  1257. drv->num_secs = 0;
  1258. drv->hard_num_cyls = drv->bridge->getMaxCylinder();
  1259. drv->num_tracks = drv->bridge->getMaxCylinder() * 2;
  1260. drv->tracklen = drv->bridge->maxMFMBitPosition();
  1261. drv->tracktiming[0] = drv->bridge->getMFMSpeed(0);
  1262. drv->multi_revolution = 1;
  1263. drv->fourms = (drv->bridge->getBitSpeed() == 4);
  1264. drv->indexoffset = 0;
  1265. drv->prevtracklen = 0;
  1266. drv->forcedwrprot = false;
  1267. drv->wrprot = drv->bridge->isWriteProtected();
  1268. drv->filetype = ADF_FLOPPYBRIDGE;
  1269. drv->useturbo = 0;
  1270. drv->mfmpos = uaerand();
  1271. drv->mfmpos |= (uaerand() << 16);
  1272. drv->mfmpos %= drv->tracklen;
  1273. drv->prevtracklen = 0;
  1274. drive_settype_id(drv); /* Set DD or HD drive */
  1275. update_drive_gui(drv - floppy, false);
  1276. update_disk_statusline(drv - floppy);
  1277. drive_fill_bigbuf(drv, fake ? -1 : 1);
  1278. return 1;
  1279. #endif
  1280. #ifdef CAPS
  1281. } else if (strncmp ((char*)buffer, "CAPS", 4) == 0) {
  1282. drv->wrprot = true;
  1283. if (!caps_loadimage (drv->diskfile, drv - floppy, &num_tracks)) {
  1284. zfile_fclose (drv->diskfile);
  1285. drv->diskfile = 0;
  1286. return 0;
  1287. }
  1288. drv->num_tracks = num_tracks;
  1289. drv->filetype = ADF_IPF;
  1290. #endif
  1291. #ifdef SCP
  1292. } else if (strncmp ((char*)buffer, "SCP", 3) == 0) {
  1293. drv->wrprot = true;
  1294. if (!scp_open (drv->diskfile, drv - floppy, &num_tracks)) {
  1295. zfile_fclose (drv->diskfile);
  1296. drv->diskfile = 0;
  1297. return 0;
  1298. }
  1299. drv->num_tracks = num_tracks;
  1300. drv->filetype = ADF_SCP;
  1301. #endif
  1302. #ifdef FDI2RAW
  1303. } else if ((drv->fdi = fdi2raw_header (drv->diskfile))) {
  1304. drv->wrprot = true;
  1305. drv->num_tracks = fdi2raw_get_last_track (drv->fdi);
  1306. drv->num_secs = fdi2raw_get_num_sector (drv->fdi);
  1307. drv->filetype = ADF_FDI;
  1308. #endif
  1309. } else if (strncmp ((char*)buffer, "UAE-1ADF", 8) == 0) {
  1310. read_header_ext2 (drv->diskfile, drv->trackdata, &drv->num_tracks, &drv->ddhd);
  1311. drv->filetype = ADF_EXT2;
  1312. drv->num_secs = 11;
  1313. if (drv->ddhd > 1)
  1314. drv->num_secs = 22;
  1315. } else if (strncmp ((char*)buffer, "UAE--ADF", 8) == 0) {
  1316. int offs = 160 * 4 + 8;
  1317. drv->wrprot = true;
  1318. drv->filetype = ADF_EXT1;
  1319. drv->num_tracks = 160;
  1320. drv->num_secs = 11;
  1321. zfile_fseek (drv->diskfile, 8, SEEK_SET);
  1322. for (int i = 0; i < 160; i++) {
  1323. tid = &drv->trackdata[i];
  1324. zfile_fread (buffer, 4, 1, drv->diskfile);
  1325. tid->sync = buffer[0] * 256 + buffer[1];
  1326. tid->len = buffer[2] * 256 + buffer[3];
  1327. tid->offs = offs;
  1328. tid->revolutions = 1;
  1329. if (tid->sync == 0) {
  1330. tid->type = TRACK_AMIGADOS;
  1331. tid->bitlen = 0;
  1332. } else {
  1333. tid->type = TRACK_RAW1;
  1334. tid->bitlen = tid->len * 8;
  1335. }
  1336. offs += tid->len;
  1337. }
  1338. } else if (memcmp (exeheader, buffer, sizeof exeheader) == 0 && !canauto && size <= 512 * (1760 * 2 - 7)) {
  1339. bool ffs = false;
  1340. int hd = 1;
  1341. int freeblocks = 1760 - 7;
  1342. int blocks_ofs = (size + FS_OFS_DATABLOCKSIZE - 1) / FS_OFS_DATABLOCKSIZE;
  1343. int extensionblocks_ofs = (blocks_ofs + FS_EXTENSION_BLOCKS - 1) / FS_EXTENSION_BLOCKS;
  1344. int blocks_ffs = (size + FS_FLOPPY_BLOCKSIZE - 1) / FS_FLOPPY_BLOCKSIZE;
  1345. int extensionblocks_ffs = (blocks_ffs + FS_EXTENSION_BLOCKS - 1) / FS_EXTENSION_BLOCKS;
  1346. // select DD+FFS if file larger than DD+OFS
  1347. if (size > FS_OFS_DATABLOCKSIZE * (freeblocks - extensionblocks_ofs)) {
  1348. ffs = true;
  1349. // select HD+FFS if file larger than DD+FFS
  1350. if (size > FS_FLOPPY_BLOCKSIZE * (freeblocks - extensionblocks_ffs)) {
  1351. hd = 2;
  1352. }
  1353. }
  1354. if (dfxtype == DRV_35_DD) {
  1355. hd = 1;
  1356. }
  1357. if (size <= 512 * (1760 * hd - 7)) {
  1358. struct zfile *z = zfile_fopen_empty(NULL, _T(""), 512 * 1760 * hd);
  1359. createimagefromexe(drv->diskfile, z, hd, ffs);
  1360. drv->filetype = ADF_NORMAL;
  1361. zfile_fclose(drv->diskfile);
  1362. drv->diskfile = z;
  1363. drv->num_tracks = 160;
  1364. drv->num_secs = 11 * hd;
  1365. for (int i = 0; i < drv->num_tracks; i++) {
  1366. tid = &drv->trackdata[i];
  1367. tid->type = TRACK_AMIGADOS;
  1368. tid->len = 512 * drv->num_secs;
  1369. tid->bitlen = 0;
  1370. tid->offs = i * 512 * drv->num_secs;
  1371. tid->revolutions = 1;
  1372. }
  1373. drv->ddhd = hd;
  1374. drv->useturbo = 1;
  1375. }
  1376. } else if (canauto && (
  1377. // 320k double sided
  1378. size == 8 * 40 * 2 * 512 ||
  1379. // 320k single sided
  1380. size == 8 * 40 * 1 * 512 ||
  1381. // 360k double sided
  1382. size == 9 * 40 * 2 * 512 ||
  1383. // 360k single sided
  1384. size == 9 * 40 * 1 * 512 ||
  1385. // 1.2M double sided
  1386. size == 15 * 80 * 2 * 512 ||
  1387. // 720k/1440k double sided
  1388. size == 9 * 80 * 2 * 512 || size == 18 * 80 * 2 * 512 || size == 10 * 80 * 2 * 512 || size == 20 * 80 * 2 * 512 || size == 21 * 80 * 2 * 512 ||
  1389. size == 9 * 81 * 2 * 512 || size == 18 * 81 * 2 * 512 || size == 10 * 81 * 2 * 512 || size == 20 * 81 * 2 * 512 || size == 21 * 81 * 2 * 512 ||
  1390. size == 9 * 82 * 2 * 512 || size == 18 * 82 * 2 * 512 || size == 10 * 82 * 2 * 512 || size == 20 * 82 * 2 * 512 || size == 21 * 82 * 2 * 512 ||
  1391. // 720k/1440k single sided
  1392. size == 9 * 80 * 1 * 512 || size == 18 * 80 * 1 * 512 || size == 10 * 80 * 1 * 512 || size == 20 * 80 * 1 * 512 ||
  1393. size == 9 * 81 * 1 * 512 || size == 18 * 81 * 1 * 512 || size == 10 * 81 * 1 * 512 || size == 20 * 81 * 1 * 512 ||
  1394. size == 9 * 82 * 1 * 512 || size == 18 * 82 * 1 * 512 || size == 10 * 82 * 1 * 512 || size == 20 * 82 * 1 * 512)) {
  1395. /* PC formatted image */
  1396. int side, sd;
  1397. drv->num_secs = 9;
  1398. drv->ddhd = 1;
  1399. sd = 0;
  1400. bool can40 = dfxtype == DRV_525_DD || dfxtype == DRV_PC_525_ONLY_40 || dfxtype == DRV_PC_525_40_80;
  1401. bool can80 = dfxtype == DRV_35_HD || dfxtype == DRV_PC_35_ONLY_80 || dfxtype == DRV_PC_525_40_80;
  1402. bool drv525 = dfxtype == DRV_525_DD || dfxtype == DRV_PC_525_ONLY_40 || dfxtype == DRV_PC_525_40_80;
  1403. for (side = 2; side > 0; side--) {
  1404. if (drv->hard_num_cyls >= 80 && can80) {
  1405. if ( size == 9 * 80 * side * 512 || size == 9 * 81 * side * 512 || size == 9 * 82 * side * 512) {
  1406. drv->num_secs = 9;
  1407. drv->ddhd = 1;
  1408. break;
  1409. } else if (!drv525 && (size == 18 * 80 * side * 512 || size == 18 * 81 * side * 512 || size == 18 * 82 * side * 512)) {
  1410. drv->num_secs = 18;
  1411. drv->ddhd = 2;
  1412. break;
  1413. } else if (!drv525 && (size == 10 * 80 * side * 512 || size == 10 * 81 * side * 512 || size == 10 * 82 * side * 512)) {
  1414. drv->num_secs = 10;
  1415. drv->ddhd = 1;
  1416. break;
  1417. } else if (!drv525 && (size == 20 * 80 * side * 512 || size == 20 * 81 * side * 512 || size == 20 * 82 * side * 512)) {
  1418. drv->num_secs = 20;
  1419. drv->ddhd = 2;
  1420. break;
  1421. } else if (!drv525 && (size == 21 * 80 * side * 512 || size == 21 * 81 * side * 512 || size == 21 * 82 * side * 512)) {
  1422. drv->num_secs = 21;
  1423. drv->ddhd = 2;
  1424. break;
  1425. } else if (size == 15 * 80 * side * 512) {
  1426. drv->num_secs = 15;
  1427. drv->ddhd = 1;
  1428. break;
  1429. }
  1430. }
  1431. if (drv->hard_num_cyls == 40 || can40) {
  1432. if (size == 9 * 40 * side * 512) {
  1433. drv->num_secs = 9;
  1434. drv->ddhd = 1;
  1435. sd = 1;
  1436. break;
  1437. } else if (size == 8 * 40 * side * 512) {
  1438. drv->num_secs = 8;
  1439. drv->ddhd = 1;
  1440. sd = 1;
  1441. break;
  1442. }
  1443. }
  1444. }
  1445. drv->num_tracks = size / (drv->num_secs * 512);
  1446. // SD disk in 5.25 drive = duplicate each track
  1447. if (sd && dfxtype == DRV_525_DD) {
  1448. drv->num_tracks *= 2;
  1449. } else {
  1450. sd = 0;
  1451. }
  1452. drv->filetype = ADF_PCDOS;
  1453. tid = &drv->trackdata[0];
  1454. for (int i = 0; i < drv->num_tracks; i++) {
  1455. tid->type = TRACK_PCDOS;
  1456. tid->len = 512 * drv->num_secs;
  1457. tid->bitlen = 0;
  1458. tid->offs = (sd ? i / 2 : i) * 512 * drv->num_secs;
  1459. if (side == 1) {
  1460. tid++;
  1461. tid->type = TRACK_NONE;
  1462. tid->len = 512 * drv->num_secs;
  1463. }
  1464. tid->revolutions = 1;
  1465. tid++;
  1466. }
  1467. drv->num_heads = side;
  1468. if (side == 1)
  1469. drv->num_tracks *= 2;
  1470. } else if ((size == 262144 || size == 524288) && buffer[0] == 0x11 && (buffer[1] == 0x11 || buffer[1] == 0x14)) {
  1471. // 256k -> KICK disk, 512k -> SuperKickstart disk
  1472. drv->filetype = size == 262144 ? ADF_KICK : ADF_SKICK;
  1473. drv->num_tracks = 1760 / (drv->num_secs = 11);
  1474. for (int i = 0; i < drv->num_tracks; i++) {
  1475. tid = &drv->trackdata[i];
  1476. tid->type = TRACK_AMIGADOS;
  1477. tid->len = 512 * drv->num_secs;
  1478. tid->bitlen = 0;
  1479. tid->offs = i * 512 * drv->num_secs - (drv->filetype == ADF_KICK ? 512 : 262144 + 1024);
  1480. tid->track = i;
  1481. tid->revolutions = 1;
  1482. }
  1483. } else {
  1484. int ds;
  1485. ds = 0;
  1486. drv->filetype = ADF_NORMAL;
  1487. /* High-density, diskspare disk or sector headers included? */
  1488. drv->num_tracks = 0;
  1489. if (size > 160 * 11 * 512 + 511) { // larger than standard adf?
  1490. for (int i = 80; i <= 83; i++) {
  1491. if (size == i * 22 * 512 * 2) { // HD
  1492. drv->ddhd = 2;
  1493. drv->num_tracks = size / (512 * (drv->num_secs = 22));
  1494. break;
  1495. }
  1496. if (size == i * 11 * 512 * 2) { // >80 cyl DD
  1497. drv->num_tracks = size / (512 * (drv->num_secs = 11));
  1498. break;
  1499. }
  1500. if (size == i * 12 * 512 * 2) { // ds 12 sectors
  1501. drv->num_tracks = size / (512 * (drv->num_secs = 12));
  1502. ds = 1;
  1503. break;
  1504. }
  1505. if (size == i * 24 * 512 * 2) { // ds 24 sectors
  1506. drv->num_tracks = size / (512 * (drv->num_secs = 24));
  1507. drv->ddhd = 2;
  1508. ds = 1;
  1509. break;
  1510. }
  1511. if (size == i * 11 * (512 + 16) * 2) { // 80+ cyl DD + headers
  1512. drv->num_tracks = size / ((512 + 16) * (drv->num_secs = 11));
  1513. drv->filetype = ADF_NORMAL_HEADER;
  1514. break;
  1515. }
  1516. if (size == i * 22 * (512 + 16) * 2) { // 80+ cyl HD + headers
  1517. drv->num_tracks = size / ((512 + 16) * (drv->num_secs = 22));
  1518. drv->filetype = ADF_NORMAL_HEADER;
  1519. break;
  1520. }
  1521. }
  1522. if (drv->num_tracks == 0) {
  1523. drv->num_tracks = size / (512 * (drv->num_secs = 22));
  1524. drv->ddhd = 2;
  1525. }
  1526. } else {
  1527. drv->num_tracks = size / (512 * (drv->num_secs = 11));
  1528. }
  1529. if (!ds && drv->num_tracks > MAX_TRACKS)
  1530. write_log (_T("Your diskfile is too big, %d bytes!\n"), size);
  1531. for (int i = 0; i < drv->num_tracks; i++) {
  1532. tid = &drv->trackdata[i];
  1533. tid->type = ds ? TRACK_DISKSPARE : TRACK_AMIGADOS;
  1534. tid->len = 512 * drv->num_secs;
  1535. tid->bitlen = 0;
  1536. tid->offs = i * 512 * drv->num_secs;
  1537. tid->revolutions = 1;
  1538. if (drv->filetype == ADF_NORMAL_HEADER) {
  1539. tid->extraoffs = drv->num_tracks * 512 * drv->num_secs + i * 16 * drv->num_secs;
  1540. } else {
  1541. tid->extraoffs = -1;
  1542. }
  1543. }
  1544. }
  1545. openwritefile (p, drv, 0);
  1546. drive_settype_id (drv); /* Set DD or HD drive */
  1547. drive_fill_bigbuf (drv, 1);
  1548. drv->mfmpos = uaerand ();
  1549. drv->mfmpos |= (uaerand () << 16);
  1550. drv->mfmpos %= drv->tracklen;
  1551. drv->prevtracklen = 0;
  1552. if (!fake) {
  1553. #ifdef DRIVESOUND
  1554. if (isfloppysound (drv))
  1555. driveclick_insert (drv - floppy, 0);
  1556. #endif
  1557. update_drive_gui (drv - floppy, false);
  1558. update_disk_statusline(drv - floppy);
  1559. }
  1560. return 1;
  1561. }
  1562. static void rand_shifter (drive *drv)
  1563. {
  1564. if (selected & (1 << (drv - floppy)))
  1565. return;
  1566. int r = ((uaerand() >> 4) & 7) + 1;
  1567. while (r-- > 0) {
  1568. word <<= 1;
  1569. word |= (uaerand() & 0x1000) ? 1 : 0;
  1570. bitoffset++;
  1571. bitoffset &= 15;
  1572. }
  1573. }
  1574. static void set_steplimit (drive *drv)
  1575. {
  1576. // emulate step limit only if cycle-exact or approximate CPU speed
  1577. if (currprefs.m68k_speed != 0)
  1578. return;
  1579. drv->steplimit = 4;
  1580. drv->steplimitcycle = get_cycles ();
  1581. }
  1582. static bool drive_empty (drive * drv)
  1583. {
  1584. #ifdef FLOPPYBRIDGE
  1585. if (drv->bridge) {
  1586. bool v = drv->bridge->isDiskInDrive();
  1587. return v == false;
  1588. }
  1589. #endif
  1590. #ifdef CATWEASEL
  1591. if (drv->catweasel)
  1592. return catweasel_disk_changed (drv->catweasel) == 0;
  1593. #endif
  1594. return drv->diskfile == 0 && drv->dskchange_time >= 0;
  1595. }
  1596. static void drive_step (drive *drv, int step_direction)
  1597. {
  1598. #ifdef CATWEASEL
  1599. if (drv->catweasel) {
  1600. int dir = direction ? -1 : 1;
  1601. catweasel_step (drv->catweasel, dir);
  1602. drv->cyl += dir;
  1603. if (drv->cyl < 0)
  1604. drv->cyl = 0;
  1605. write_log (_T("%d -> %d\n"), dir, drv->cyl);
  1606. return;
  1607. }
  1608. #endif
  1609. if (!drive_empty (drv))
  1610. drv->dskchange = 0;
  1611. #ifdef FLOPPYBRIDGE
  1612. if (drv->bridge) {
  1613. int dir = step_direction ? -1 : 1;
  1614. drv->cyl += dir;
  1615. if (drv->cyl < 0) {
  1616. drv->cyl = 0;
  1617. drv->bridge->handleNoClickStep(side);
  1618. } else {
  1619. if (drv->cyl >= drv->bridge->getMaxCylinder()) {
  1620. drv->cyl = drv->bridge->getMaxCylinder() - 1;
  1621. }
  1622. drv->bridge->gotoCylinder(drv->cyl, side);
  1623. }
  1624. return;
  1625. }
  1626. #endif
  1627. if (drv->steplimit && get_cycles() - drv->steplimitcycle < MIN_STEPLIMIT_CYCLE) {
  1628. write_log (_T(" step ignored drive %ld, %lu\n"),
  1629. drv - floppy, (get_cycles() - drv->steplimitcycle) / CYCLE_UNIT);
  1630. return;
  1631. }
  1632. /* A1200's floppy drive needs at least 30 raster lines between steps
  1633. * but we'll use very small value for better compatibility with faster CPU emulation
  1634. * (stupid trackloaders with CPU delay loops)
  1635. */
  1636. set_steplimit (drv);
  1637. if (step_direction) {
  1638. if (drv->cyl) {
  1639. drv->cyl--;
  1640. #ifdef DRIVESOUND
  1641. if (isfloppysound (drv))
  1642. driveclick_click (drv - floppy, drv->cyl);
  1643. #endif
  1644. }
  1645. /* else
  1646. write_log (_T("program tried to step beyond track zero\n"));
  1647. "no-click" programs does that
  1648. */
  1649. } else {
  1650. int maxtrack = drv->hard_num_cyls;
  1651. if (drv->cyl < maxtrack + 3) {
  1652. drv->cyl++;
  1653. #ifdef CATWEASEL
  1654. if (drv->catweasel)
  1655. catweasel_step (drv->catweasel, 1);
  1656. #endif
  1657. }
  1658. if (drv->cyl >= maxtrack)
  1659. write_log (_T("program tried to step over track %d PC %08x\n"), maxtrack, M68K_GETPC);
  1660. #ifdef DRIVESOUND
  1661. if (isfloppysound (drv))
  1662. driveclick_click (drv - floppy, drv->cyl);
  1663. #endif
  1664. }
  1665. rand_shifter (drv);
  1666. if (disk_debug_logging > 2)
  1667. write_log (_T(" ->step %d"), drv->cyl);
  1668. }
  1669. static bool drive_track0 (drive * drv)
  1670. {
  1671. #ifdef FLOPPYBRIDG

Large files files are truncated, but you can click here to view the full file