2
0

abcdisk.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. /*
  2. * abcdisk.c
  3. *
  4. * Emulate an ABC80/800 disk controller
  5. */
  6. #include <string.h>
  7. #include <stdio.h>
  8. #include "fw.h"
  9. #include "io.h"
  10. #include "abcio.h"
  11. #include "console.h"
  12. #include "ff.h"
  13. /* Option flags, mostly for debugging */
  14. #define NOTTHERE 0
  15. #define READONLY 0
  16. #define INTERLEAVE 0
  17. #define FORMAT_SUPPORT 0
  18. enum drive_flags {
  19. DF_MOUNTED, /* Host file open, drive exported */
  20. DF_READONLY, /* Drive is readonly */
  21. DF_DISABLED /* Drive is disabled */
  22. };
  23. enum pending {
  24. PEND_IO = 1,
  25. PEND_RESET = 2
  26. };
  27. /* Per-drive state */
  28. struct drive_state {
  29. FIL file; /* Host file */
  30. char name[4]; /* Drive name */
  31. uint16_t sectors; /* Total size in 256-byte sectors */
  32. #if INTERLEAVE
  33. uint8_t ilmsk, ilfac; /* Software interleaving parameters */
  34. #endif
  35. enum drive_flags flags;
  36. enum drive_flags force; /* Option to force flags */
  37. };
  38. /* Fixed parameters for each controller */
  39. struct ctl_params {
  40. uint8_t clustshift; /* log2(clustersize/256) */
  41. uint8_t devsel; /* I/O device select */
  42. uint16_t maxsectors; /* Maximum sectors for this controller */
  43. uint8_t c, h, s; /* Disk geometry */
  44. bool newaddr; /* "New addressing" */
  45. const char name[4]; /* Name of controller (disk type) */
  46. #if INTERLEAVE
  47. uint8_t ilmsk, ilfac; /* Software interleaving parea */
  48. #endif
  49. #if FORMAT_SUPPORT
  50. bool fmtdata_i_buf; /* Use user-provided formatting data */
  51. #endif
  52. } __attribute__((aligned(4)));
  53. /* Per-controller state */
  54. struct ctl_state {
  55. struct abc_dev iodev;
  56. const struct ctl_params *params;
  57. uint8_t k[4]; /* Command bytes */
  58. uint8_t drives; /* Total drives present */
  59. bool initialized; /* Controller initialized */
  60. volatile enum pending pending; /* Need to do I/O */
  61. struct drive_state drv[8]; /* Per-drive state */
  62. uint8_t buf[4][256]; /* 4 host buffers @ 256 bytes */
  63. };
  64. /*
  65. * DOSGEN depends on this value... and different DOSGEN
  66. * expect different values. If this value is wrong, DOSGEN
  67. * will spin forever on "testing sector..."
  68. */
  69. #define OUT_OF_RANGE 0x21 /* Status code for an invalid sector */
  70. #define DISK_NOT_READY 0x80
  71. #define WRITE_PROTECT 0x40
  72. #define WRITE_FAULT 0x20
  73. #define CRC_ERROR 0x08
  74. enum controller_types {
  75. MOx,
  76. MFx,
  77. SFx,
  78. HDx,
  79. CONTROLLER_TYPES
  80. };
  81. #if INTERLEAVE
  82. # define IL(mask, fac) .ilmsk = (mask), .ilfac = (fac),
  83. #else
  84. # define IL(mask, fac)
  85. #endif
  86. static const struct ctl_params parameters[CONTROLLER_TYPES] = {
  87. /*
  88. * MOx: covers all of these formats:
  89. * SSSD = 40×8×1 (80K, FD2/DD80),
  90. * SSDD = 40×16×1 (160K, FD2D/DD82/ABC830) and
  91. * DSDD = 40×16×2 (320K, FD4D/DD84/DD52)
  92. */
  93. [MOx] = {
  94. .devsel = 45,
  95. .clustshift = 0,
  96. .maxsectors = 40 * 2 * 16,
  97. .c = 40, .h = 2, .s = 16,
  98. .name = "mo",
  99. #if FORMAT_SUPPORT
  100. .fmtdata_in_buf = true,
  101. #endif
  102. IL(15, 7)
  103. },
  104. /* MFx: DSQD = 80×16x2 (640K, ABC832/834) */
  105. [MFx] = {
  106. .devsel = 44,
  107. .clustshift = 2,
  108. .maxsectors = 80 * 2 * 16,
  109. .c = 80, .h = 2, .s = 16,
  110. .name = "mf"
  111. },
  112. /* SFx: 8" floppy (DD88, ABC838) */
  113. [SFx] = {
  114. .devsel = 46,
  115. .clustshift = 2,
  116. .maxsectors = (77 * 2 - 1) * 26, /* Track 0, side 0 not used */
  117. .c = 77, .h = 2, .s = 26,
  118. .name = "sf"
  119. },
  120. [HDx] = {
  121. .devsel = 36,
  122. .clustshift = 5,
  123. .newaddr = true, /* Actually irrelevant for clustshift = 5 */
  124. .maxsectors = (239 * 8 - 1) * 32, /* Maximum supported by UFD-DOS */
  125. .c = 238, .h = 16, .s = 64,
  126. .name = "hd"
  127. }
  128. };
  129. static struct ctl_state __dram_bss controllers[CONTROLLER_TYPES];
  130. static inline bool mounted(const struct drive_state *drv)
  131. {
  132. return !!(drv->flags & DF_MOUNTED);
  133. }
  134. static inline struct drive_state *cur_drv_mutable(struct ctl_state *state)
  135. {
  136. return &state->drv[state->k[1] & 7];
  137. }
  138. static inline const struct drive_state *cur_drv(const struct ctl_state *state)
  139. {
  140. return &state->drv[state->k[1] & 7];
  141. }
  142. static inline unsigned int cur_sector(const struct ctl_state *state)
  143. {
  144. uint8_t k2 = state->k[2], k3 = state->k[3];
  145. if (state->params->newaddr)
  146. return (k2 << 8) + k3;
  147. else
  148. return (((k2 << 3) + (k3 >> 5)) << state->params->clustshift)
  149. + (k3 & 31);
  150. }
  151. /* Get physical sector number, after interleaving */
  152. static inline unsigned int
  153. virt2phys(const struct drive_state *drv, unsigned int sector)
  154. {
  155. #if INTERLEAVE
  156. unsigned int ilmsk = drv->ilmsk;
  157. unsigned int ilfac = drv->ilfac;
  158. sector = (sector & ~ilmsk) | ((sector * ilfac) & ilmsk);
  159. #endif
  160. return sector;
  161. }
  162. static inline unsigned int phys_sector(const struct ctl_state *state)
  163. {
  164. return virt2phys(cur_drv(state), cur_sector(state));
  165. }
  166. static inline unsigned int file_pos(const struct ctl_state *state)
  167. {
  168. return phys_sector(state) << 8;
  169. }
  170. static inline bool file_pos_valid(const struct ctl_state *state)
  171. {
  172. return phys_sector(state) < cur_drv(state)->sectors;
  173. }
  174. static inline bool cur_sector_valid(const struct ctl_state *state)
  175. {
  176. uint8_t k3 = state->k[3];
  177. if (!state->params->newaddr && ((k3 & 31) >> state->params->clustshift))
  178. return false;
  179. return phys_sector(state) < state->params->maxsectors;
  180. }
  181. static inline uint8_t *cur_buf(struct ctl_state *state)
  182. {
  183. return state->buf[state->k[1] >> 6];
  184. }
  185. static void disk_start_command(struct ctl_state *state)
  186. {
  187. abc_setup_out_queue(&state->iodev, state->k, 4, 0x81);
  188. }
  189. static void sync_drives(struct ctl_state *state)
  190. {
  191. for (int i = 0; i < 8; i++)
  192. if (state->drv[i].flags & DF_MOUNTED)
  193. f_sync(&state->drv[i].file);
  194. }
  195. static void disk_set_error(struct ctl_state *state, unsigned int error)
  196. {
  197. abc_set_inp_default(&state->iodev, error);
  198. }
  199. static void disk_reset_state(struct ctl_state *state)
  200. {
  201. abc_set_inp_status(&state->iodev, 0);
  202. disk_set_error(state, 0);
  203. sync_drives(state);
  204. disk_start_command(state);
  205. }
  206. static struct drive_state *
  207. name_to_drive(const char *drive)
  208. {
  209. struct ctl_state *state;
  210. unsigned int ndrive;
  211. /* All drive names are three letters long */
  212. if (strlen(drive) != 3)
  213. return NULL;
  214. ndrive = drive[2] - '0';
  215. if (ndrive > 7)
  216. return NULL;
  217. if (!memcmp("dr", drive, 2)) {
  218. /* DRx alias for MOx (matches "old DOS") */
  219. return &controllers[MOx].drv[ndrive];
  220. }
  221. for (int i = 0; i < CONTROLLER_TYPES; i++) {
  222. struct ctl_state *state = &controllers[i];
  223. if (!memcmp(state->params->name, drive, 2))
  224. return &state->drv[ndrive];
  225. }
  226. return NULL; /* No such disk */
  227. }
  228. bool valid_drive_name(const char *drive)
  229. {
  230. return name_to_drive(drive) != NULL;
  231. }
  232. static int mount_drive(struct drive_state *drv, struct ctl_state *state,
  233. const char *filename)
  234. {
  235. if (mounted(drv)) {
  236. f_close(&drv->file);
  237. drv->flags &= ~DF_MOUNTED;
  238. }
  239. if (drv->force & DF_DISABLED)
  240. return -1;
  241. drv->flags = drv->force & ~DF_MOUNTED;
  242. if (!filename) {
  243. return 0; /* Explicit unmount */
  244. } else {
  245. while (1) {
  246. BYTE mode = FA_OPEN_EXISTING | FA_READ;
  247. if (!(drv->flags & DF_READONLY))
  248. mode |= FA_WRITE;
  249. FRESULT rv = f_open(&drv->file, filename, mode);
  250. if (rv == FR_WRITE_PROTECTED && (mode & FA_WRITE)) {
  251. drv->flags |= DF_READONLY;
  252. continue;
  253. }
  254. if (rv != FR_OK)
  255. drv->flags |= DF_DISABLED;
  256. else
  257. drv->flags |= DF_MOUNTED;
  258. break;
  259. }
  260. if (!(drv->flags & DF_MOUNTED))
  261. return -1;
  262. con_printf("abcdisk: %-3s = %s\n", drv->name, filename);
  263. }
  264. /*
  265. * Smaller than the standard disk size? Treat the sectors
  266. * beyond the end as bad.
  267. */
  268. unsigned int filesec = f_size(&drv->file) >> 8;
  269. drv->sectors = min(filesec, state->params->maxsectors);
  270. /* Interleaving parameters */
  271. #if INTERLEAVE
  272. drv->ilfac = state->params->ilfac;
  273. drv->ilmsk = state->params->ilmsk;
  274. #endif
  275. return 0;
  276. }
  277. #define IDLE_CALLBACK_MASK (1 << 4)
  278. static void abcdisk_callback_out(struct abc_dev *dev, uint8_t data)
  279. {
  280. struct ctl_state *state = container_of(dev, struct ctl_state, iodev);
  281. dev->callback_mask = IDLE_CALLBACK_MASK;
  282. ABC_INP1_DATA = dev->inp_data[1] = 0;
  283. state->pending |= PEND_IO;
  284. }
  285. static void abcdisk_callback_inp(struct abc_dev *dev)
  286. {
  287. struct ctl_state *state = container_of(dev, struct ctl_state, iodev);
  288. dev->callback_mask = IDLE_CALLBACK_MASK;
  289. ABC_INP1_DATA = dev->inp_data[1] = 0;
  290. state->pending |= PEND_IO;
  291. }
  292. static void abcdisk_callback_cmd(struct abc_dev *dev, uint8_t data, uint8_t addr)
  293. {
  294. struct ctl_state *state = container_of(dev, struct ctl_state, iodev);
  295. if (addr == 4)
  296. state->pending |= PEND_RESET;
  297. }
  298. static char * const disk_pfx[] = {
  299. "/abcdisk.800/", "/abcdisk/", "/abcdisk.", "/", NULL
  300. };
  301. static void init_drives(struct ctl_state *state)
  302. {
  303. static bool disk_initialized;
  304. static int disk_init_status;
  305. uint32_t abc_status = ABC_STATUS;
  306. const char * const *pfx_list;
  307. int i;
  308. if (!disk_initialized) {
  309. disk_init_status = disk_init();
  310. disk_initialized = true;
  311. }
  312. /* .80/ or .800/ for the first entry */
  313. strcpy(disk_pfx[0] + 10 + !!(abc_status & ABC_STATUS_800), "0/");
  314. /* If any of these don't exist we simply report device not ready */
  315. state->drives = 0;
  316. if (!disk_init_status) {
  317. for (i = 0; i < 8; i++) {
  318. struct drive_state *drv = &state->drv[i];
  319. unsigned int filesec;
  320. char * const *pfx;
  321. snprintf(drv->name, sizeof drv->name, "%-.2s%c",
  322. state->params->name, i + '0');
  323. for (pfx = disk_pfx; *pfx; pfx++) {
  324. char filename_buf[64];
  325. snprintf(filename_buf, sizeof filename_buf,
  326. "%s%s", *pfx, drv->name);
  327. if (!mount_drive(drv, state, filename_buf)) {
  328. state->drives++;
  329. break;
  330. }
  331. }
  332. }
  333. }
  334. }
  335. static void do_next_command(struct ctl_state *state)
  336. {
  337. struct drive_state *drv = cur_drv_mutable(state);
  338. uint8_t *buf = cur_buf(state);
  339. if (state->k[0] & 0x01) {
  340. /* READ SECTOR */
  341. if (!(drv->flags & DF_MOUNTED)) {
  342. disk_set_error(state, DISK_NOT_READY);
  343. } else if (!cur_sector_valid(state)) {
  344. disk_set_error(state, OUT_OF_RANGE);
  345. } else if (!file_pos_valid(state)) {
  346. disk_set_error(state, CRC_ERROR);
  347. } else {
  348. UINT rlen = 0;
  349. FRESULT rv;
  350. rv = f_lseek(&drv->file, file_pos(state));
  351. if (rv == FR_OK)
  352. rv = f_read(&drv->file, buf, 256, &rlen);
  353. if (rv != FR_OK || rlen != 256) {
  354. disk_set_error(state, CRC_ERROR);
  355. }
  356. }
  357. state->k[0] &= ~0x01; /* Command done */
  358. }
  359. if (state->k[0] & 0x02) {
  360. /* SECTOR TO HOST */
  361. state->k[0] &= ~0x02; /* Command done */
  362. abc_setup_inp_queue(&state->iodev, buf, 256, 0x01);
  363. return;
  364. }
  365. if (state->k[0] & 0x04) {
  366. /* SECTOR FROM HOST */
  367. state->k[0] &= ~0x04; /* Command done */
  368. abc_setup_out_queue(&state->iodev, buf, 256, 0x01);
  369. return;
  370. }
  371. if (state->k[0] & 0x08) {
  372. /* WRITE SECTOR */
  373. if (!(drv->flags & DF_MOUNTED)) {
  374. disk_set_error(state, DISK_NOT_READY);
  375. } else if (drv->flags & DF_READONLY) {
  376. disk_set_error(state, WRITE_PROTECT);
  377. } else if (!cur_sector_valid(state)) {
  378. disk_set_error(state, OUT_OF_RANGE);
  379. } else if (!file_pos_valid(state)) {
  380. disk_set_error(state, CRC_ERROR);
  381. } else {
  382. UINT wlen = 0;
  383. FRESULT rv;
  384. rv = f_lseek(&drv->file, file_pos(state));
  385. if (rv == FR_OK)
  386. rv = f_write(&drv->file, buf, 256, &wlen);
  387. if (rv != FR_OK || wlen != 256)
  388. disk_set_error(state, WRITE_FAULT);
  389. }
  390. state->k[0] &= ~0x08; /* Command done */
  391. }
  392. #if FORMAT_SUPPORT
  393. /* This code needs additional work */
  394. if (state->k[0] & 0x10 && state->k[1] & 0x08) {
  395. state->out_ptr = 0;
  396. /* FORMAT */
  397. if (!drv->hf) {
  398. state->error = 0x80; /* Not ready */
  399. } else if (!file_wrok(hf)) {
  400. state->error = 0x40; /* Write protect */
  401. } else {
  402. unsigned int s, c0, c1, s0, s1;
  403. unsigned int cylsec = state->s * state->h;
  404. uint8_t data[256];
  405. unsigned int fmtsec, filesec;
  406. /* Sector count produced by format */
  407. fmtsec = state->params->maxsectors;
  408. /* For non-MO-drives, this seems to be internally generated */
  409. memset(data, 0x40, 256);
  410. if (state->fmtdata_in_buf) {
  411. /*
  412. * MO drives put the sector image in the buffers, for
  413. * backwards compatibility and to support single density.
  414. *
  415. * Right before the F7 header CRC opcode is a density byte;
  416. * 00 for single, and 01 for double. The data begins after
  417. * a byte of FB.
  418. */
  419. bool single = false;
  420. const uint8_t *p, *ep;
  421. ep = state->buf[1];
  422. for (p = state->buf[0]+1; p < ep; p++) {
  423. if (*p == 0xf7)
  424. single = (p[-1] == 0);
  425. if (*p == 0xfb)
  426. break;
  427. }
  428. fmtsec >>= single;
  429. if (*p++ == 0xfb) { /* Data block found */
  430. if (single) {
  431. /* Really two 128-byte sectors! */
  432. memcpy(data, p, 128);
  433. memcpy(data+128, p, 128);
  434. } else {
  435. memcpy(data, p, 256);
  436. }
  437. }
  438. }
  439. /*
  440. * Adjust the size of the accessible device to the smallest
  441. * of the physical file and the formatted size
  442. */
  443. filesec = drv->hf->filesize >> 8;
  444. drv->sectors = (filesec && filesec < fmtsec) ? filesec : fmtsec;
  445. /*
  446. * k2 and k3 contain the first and last cylinder numbers to
  447. * format, inclusively. The last cylinder may be partial due
  448. * to virtual remapping, e.g. for sf floppies.
  449. */
  450. c0 = state->k[2];
  451. s0 = c0 * cylsec;
  452. c1 = state->k[3] + 1;
  453. s1 = c1 * cylsec;
  454. if (tracing(TRACE_DISK)) {
  455. fprintf(tracef, "%s: formatting cyl %u..%u, sectors %u..%u\n",
  456. drv->name, c0, c1-1, s0, s1-1);
  457. }
  458. clearerr(hf->f);
  459. state->error = 0;
  460. for (s = s0; s < s1; s++) {
  461. unsigned int ps = virt2phys(drv, s);
  462. if (ps >= drv->sectors) {
  463. state->error |= 0x02; /* Track 0/Lost data? */
  464. break;
  465. } else if (hf->map) {
  466. memcpy(hf->map + (ps << 8), data, 256);
  467. } else {
  468. fseek(hf->f, ps << 8, SEEK_SET);
  469. fwrite(data, 1, 256, hf->f);
  470. }
  471. }
  472. if (ferror(hf->f))
  473. state->error |= 0x20; /* Write fault */
  474. }
  475. state->k[1] &= ~0x08;
  476. }
  477. #endif /* FORMAT support */
  478. if (!(state->k[1] & 0x38))
  479. state->k[0] &= ~0x10;
  480. disk_start_command(state);
  481. }
  482. #define SYNC_TIME (2*CPU_HZ)
  483. /* Called from the main loop */
  484. void abcdisk_io_poll(void)
  485. {
  486. static uint32_t last_sync;
  487. uint32_t now = rdtime();
  488. bool need_sync = (now - last_sync) >= SYNC_TIME;
  489. last_sync = now;
  490. for (int i = 0; i < CONTROLLER_TYPES; i++) {
  491. struct ctl_state *state = &controllers[i];
  492. enum pending pending;
  493. mask_irq(ABC_IRQ);
  494. pending = state->pending;
  495. state->pending = 0;
  496. unmask_irq(ABC_IRQ);
  497. if (!pending)
  498. continue;
  499. if (pending & PEND_RESET) {
  500. if (state->initialized)
  501. disk_reset_state(state);
  502. }
  503. if (pending & PEND_IO) {
  504. if (!state->initialized)
  505. init_drives(state);
  506. do_next_command(state);
  507. }
  508. if (need_sync)
  509. sync_drives(state);
  510. }
  511. }
  512. /*
  513. * Called during initialization. Don't initialize the SD card here;
  514. * it will take too long and ABC will time out claiming no drives present.
  515. */
  516. void abcdisk_init(void)
  517. {
  518. static const struct abc_dev iodev_template = {
  519. .callback_mask = IDLE_CALLBACK_MASK,
  520. .status_first_out_mask = (uint8_t)~0x80,
  521. .status_first_inp_mask = (uint8_t)~0x80,
  522. .callback_out = abcdisk_callback_out,
  523. .callback_inp = abcdisk_callback_inp,
  524. .callback_cmd = abcdisk_callback_cmd
  525. };
  526. for (int i = 0; i < CONTROLLER_TYPES; i++) {
  527. struct ctl_state *state = &controllers[i];
  528. state->params = &parameters[i];
  529. state->iodev = iodev_template;
  530. disk_reset_state(state);
  531. abc_register(&state->iodev, state->params->devsel);
  532. }
  533. }