fdc.c 69 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284
  1. /*
  2. * QEMU Floppy disk emulator (Intel 82078)
  3. *
  4. * Copyright (c) 2003, 2007 Jocelyn Mayer
  5. * Copyright (c) 2008 Hervé Poussineau
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. * THE SOFTWARE.
  24. */
  25. /*
  26. * The controller is used in Sun4m systems in a slightly different
  27. * way. There are changes in DOR register and DMA is not available.
  28. */
  29. #include "hw.h"
  30. #include "fdc.h"
  31. #include "qemu/error-report.h"
  32. #include "qemu/timer.h"
  33. #include "isa.h"
  34. #include "sysbus.h"
  35. #include "qdev-addr.h"
  36. #include "sysemu/blockdev.h"
  37. #include "sysemu/sysemu.h"
  38. #include "qemu/log.h"
  39. /********************************************************/
  40. /* debug Floppy devices */
  41. //#define DEBUG_FLOPPY
  42. #ifdef DEBUG_FLOPPY
  43. #define FLOPPY_DPRINTF(fmt, ...) \
  44. do { printf("FLOPPY: " fmt , ## __VA_ARGS__); } while (0)
  45. #else
  46. #define FLOPPY_DPRINTF(fmt, ...)
  47. #endif
  48. /********************************************************/
  49. /* Floppy drive emulation */
  50. typedef enum FDriveRate {
  51. FDRIVE_RATE_500K = 0x00, /* 500 Kbps */
  52. FDRIVE_RATE_300K = 0x01, /* 300 Kbps */
  53. FDRIVE_RATE_250K = 0x02, /* 250 Kbps */
  54. FDRIVE_RATE_1M = 0x03, /* 1 Mbps */
  55. } FDriveRate;
  56. typedef struct FDFormat {
  57. FDriveType drive;
  58. uint8_t last_sect;
  59. uint8_t max_track;
  60. uint8_t max_head;
  61. FDriveRate rate;
  62. } FDFormat;
  63. static const FDFormat fd_formats[] = {
  64. /* First entry is default format */
  65. /* 1.44 MB 3"1/2 floppy disks */
  66. { FDRIVE_DRV_144, 18, 80, 1, FDRIVE_RATE_500K, },
  67. { FDRIVE_DRV_144, 20, 80, 1, FDRIVE_RATE_500K, },
  68. { FDRIVE_DRV_144, 21, 80, 1, FDRIVE_RATE_500K, },
  69. { FDRIVE_DRV_144, 21, 82, 1, FDRIVE_RATE_500K, },
  70. { FDRIVE_DRV_144, 21, 83, 1, FDRIVE_RATE_500K, },
  71. { FDRIVE_DRV_144, 22, 80, 1, FDRIVE_RATE_500K, },
  72. { FDRIVE_DRV_144, 23, 80, 1, FDRIVE_RATE_500K, },
  73. { FDRIVE_DRV_144, 24, 80, 1, FDRIVE_RATE_500K, },
  74. /* 2.88 MB 3"1/2 floppy disks */
  75. { FDRIVE_DRV_288, 36, 80, 1, FDRIVE_RATE_1M, },
  76. { FDRIVE_DRV_288, 39, 80, 1, FDRIVE_RATE_1M, },
  77. { FDRIVE_DRV_288, 40, 80, 1, FDRIVE_RATE_1M, },
  78. { FDRIVE_DRV_288, 44, 80, 1, FDRIVE_RATE_1M, },
  79. { FDRIVE_DRV_288, 48, 80, 1, FDRIVE_RATE_1M, },
  80. /* 720 kB 3"1/2 floppy disks */
  81. { FDRIVE_DRV_144, 9, 80, 1, FDRIVE_RATE_250K, },
  82. { FDRIVE_DRV_144, 10, 80, 1, FDRIVE_RATE_250K, },
  83. { FDRIVE_DRV_144, 10, 82, 1, FDRIVE_RATE_250K, },
  84. { FDRIVE_DRV_144, 10, 83, 1, FDRIVE_RATE_250K, },
  85. { FDRIVE_DRV_144, 13, 80, 1, FDRIVE_RATE_250K, },
  86. { FDRIVE_DRV_144, 14, 80, 1, FDRIVE_RATE_250K, },
  87. /* 1.2 MB 5"1/4 floppy disks */
  88. { FDRIVE_DRV_120, 15, 80, 1, FDRIVE_RATE_500K, },
  89. { FDRIVE_DRV_120, 18, 80, 1, FDRIVE_RATE_500K, },
  90. { FDRIVE_DRV_120, 18, 82, 1, FDRIVE_RATE_500K, },
  91. { FDRIVE_DRV_120, 18, 83, 1, FDRIVE_RATE_500K, },
  92. { FDRIVE_DRV_120, 20, 80, 1, FDRIVE_RATE_500K, },
  93. /* 720 kB 5"1/4 floppy disks */
  94. { FDRIVE_DRV_120, 9, 80, 1, FDRIVE_RATE_250K, },
  95. { FDRIVE_DRV_120, 11, 80, 1, FDRIVE_RATE_250K, },
  96. /* 360 kB 5"1/4 floppy disks */
  97. { FDRIVE_DRV_120, 9, 40, 1, FDRIVE_RATE_300K, },
  98. { FDRIVE_DRV_120, 9, 40, 0, FDRIVE_RATE_300K, },
  99. { FDRIVE_DRV_120, 10, 41, 1, FDRIVE_RATE_300K, },
  100. { FDRIVE_DRV_120, 10, 42, 1, FDRIVE_RATE_300K, },
  101. /* 320 kB 5"1/4 floppy disks */
  102. { FDRIVE_DRV_120, 8, 40, 1, FDRIVE_RATE_250K, },
  103. { FDRIVE_DRV_120, 8, 40, 0, FDRIVE_RATE_250K, },
  104. /* 360 kB must match 5"1/4 better than 3"1/2... */
  105. { FDRIVE_DRV_144, 9, 80, 0, FDRIVE_RATE_250K, },
  106. /* end */
  107. { FDRIVE_DRV_NONE, -1, -1, 0, 0, },
  108. };
  109. static void pick_geometry(BlockDriverState *bs, int *nb_heads,
  110. int *max_track, int *last_sect,
  111. FDriveType drive_in, FDriveType *drive,
  112. FDriveRate *rate)
  113. {
  114. const FDFormat *parse;
  115. uint64_t nb_sectors, size;
  116. int i, first_match, match;
  117. bdrv_get_geometry(bs, &nb_sectors);
  118. match = -1;
  119. first_match = -1;
  120. for (i = 0; ; i++) {
  121. parse = &fd_formats[i];
  122. if (parse->drive == FDRIVE_DRV_NONE) {
  123. break;
  124. }
  125. if (drive_in == parse->drive ||
  126. drive_in == FDRIVE_DRV_NONE) {
  127. size = (parse->max_head + 1) * parse->max_track *
  128. parse->last_sect;
  129. if (nb_sectors == size) {
  130. match = i;
  131. break;
  132. }
  133. if (first_match == -1) {
  134. first_match = i;
  135. }
  136. }
  137. }
  138. if (match == -1) {
  139. if (first_match == -1) {
  140. match = 1;
  141. } else {
  142. match = first_match;
  143. }
  144. parse = &fd_formats[match];
  145. }
  146. *nb_heads = parse->max_head + 1;
  147. *max_track = parse->max_track;
  148. *last_sect = parse->last_sect;
  149. *drive = parse->drive;
  150. *rate = parse->rate;
  151. }
  152. #define GET_CUR_DRV(fdctrl) ((fdctrl)->cur_drv)
  153. #define SET_CUR_DRV(fdctrl, drive) ((fdctrl)->cur_drv = (drive))
  154. /* Will always be a fixed parameter for us */
  155. #define FD_SECTOR_LEN 512
  156. #define FD_SECTOR_SC 2 /* Sector size code */
  157. #define FD_RESET_SENSEI_COUNT 4 /* Number of sense interrupts on RESET */
  158. typedef struct FDCtrl FDCtrl;
  159. /* Floppy disk drive emulation */
  160. typedef enum FDiskFlags {
  161. FDISK_DBL_SIDES = 0x01,
  162. } FDiskFlags;
  163. typedef struct FDrive {
  164. FDCtrl *fdctrl;
  165. BlockDriverState *bs;
  166. /* Drive status */
  167. FDriveType drive;
  168. uint8_t perpendicular; /* 2.88 MB access mode */
  169. /* Position */
  170. uint8_t head;
  171. uint8_t track;
  172. uint8_t sect;
  173. /* Media */
  174. FDiskFlags flags;
  175. uint8_t last_sect; /* Nb sector per track */
  176. uint8_t max_track; /* Nb of tracks */
  177. uint16_t bps; /* Bytes per sector */
  178. uint8_t ro; /* Is read-only */
  179. uint8_t media_changed; /* Is media changed */
  180. uint8_t media_rate; /* Data rate of medium */
  181. } FDrive;
  182. static void fd_init(FDrive *drv)
  183. {
  184. /* Drive */
  185. drv->drive = FDRIVE_DRV_NONE;
  186. drv->perpendicular = 0;
  187. /* Disk */
  188. drv->last_sect = 0;
  189. drv->max_track = 0;
  190. }
  191. #define NUM_SIDES(drv) ((drv)->flags & FDISK_DBL_SIDES ? 2 : 1)
  192. static int fd_sector_calc(uint8_t head, uint8_t track, uint8_t sect,
  193. uint8_t last_sect, uint8_t num_sides)
  194. {
  195. return (((track * num_sides) + head) * last_sect) + sect - 1;
  196. }
  197. /* Returns current position, in sectors, for given drive */
  198. static int fd_sector(FDrive *drv)
  199. {
  200. return fd_sector_calc(drv->head, drv->track, drv->sect, drv->last_sect,
  201. NUM_SIDES(drv));
  202. }
  203. /* Seek to a new position:
  204. * returns 0 if already on right track
  205. * returns 1 if track changed
  206. * returns 2 if track is invalid
  207. * returns 3 if sector is invalid
  208. * returns 4 if seek is disabled
  209. */
  210. static int fd_seek(FDrive *drv, uint8_t head, uint8_t track, uint8_t sect,
  211. int enable_seek)
  212. {
  213. uint32_t sector;
  214. int ret;
  215. if (track > drv->max_track ||
  216. (head != 0 && (drv->flags & FDISK_DBL_SIDES) == 0)) {
  217. FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n",
  218. head, track, sect, 1,
  219. (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,
  220. drv->max_track, drv->last_sect);
  221. return 2;
  222. }
  223. if (sect > drv->last_sect) {
  224. FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n",
  225. head, track, sect, 1,
  226. (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,
  227. drv->max_track, drv->last_sect);
  228. return 3;
  229. }
  230. sector = fd_sector_calc(head, track, sect, drv->last_sect, NUM_SIDES(drv));
  231. ret = 0;
  232. if (sector != fd_sector(drv)) {
  233. #if 0
  234. if (!enable_seek) {
  235. FLOPPY_DPRINTF("error: no implicit seek %d %02x %02x"
  236. " (max=%d %02x %02x)\n",
  237. head, track, sect, 1, drv->max_track,
  238. drv->last_sect);
  239. return 4;
  240. }
  241. #endif
  242. drv->head = head;
  243. if (drv->track != track) {
  244. if (drv->bs != NULL && bdrv_is_inserted(drv->bs)) {
  245. drv->media_changed = 0;
  246. }
  247. ret = 1;
  248. }
  249. drv->track = track;
  250. drv->sect = sect;
  251. }
  252. if (drv->bs == NULL || !bdrv_is_inserted(drv->bs)) {
  253. ret = 2;
  254. }
  255. return ret;
  256. }
  257. /* Set drive back to track 0 */
  258. static void fd_recalibrate(FDrive *drv)
  259. {
  260. FLOPPY_DPRINTF("recalibrate\n");
  261. fd_seek(drv, 0, 0, 1, 1);
  262. }
  263. /* Revalidate a disk drive after a disk change */
  264. static void fd_revalidate(FDrive *drv)
  265. {
  266. int nb_heads, max_track, last_sect, ro;
  267. FDriveType drive;
  268. FDriveRate rate;
  269. FLOPPY_DPRINTF("revalidate\n");
  270. if (drv->bs != NULL) {
  271. ro = bdrv_is_read_only(drv->bs);
  272. pick_geometry(drv->bs, &nb_heads, &max_track,
  273. &last_sect, drv->drive, &drive, &rate);
  274. if (!bdrv_is_inserted(drv->bs)) {
  275. FLOPPY_DPRINTF("No disk in drive\n");
  276. } else {
  277. FLOPPY_DPRINTF("Floppy disk (%d h %d t %d s) %s\n", nb_heads,
  278. max_track, last_sect, ro ? "ro" : "rw");
  279. }
  280. if (nb_heads == 1) {
  281. drv->flags &= ~FDISK_DBL_SIDES;
  282. } else {
  283. drv->flags |= FDISK_DBL_SIDES;
  284. }
  285. drv->max_track = max_track;
  286. drv->last_sect = last_sect;
  287. drv->ro = ro;
  288. drv->drive = drive;
  289. drv->media_rate = rate;
  290. } else {
  291. FLOPPY_DPRINTF("No drive connected\n");
  292. drv->last_sect = 0;
  293. drv->max_track = 0;
  294. drv->flags &= ~FDISK_DBL_SIDES;
  295. }
  296. }
  297. /********************************************************/
  298. /* Intel 82078 floppy disk controller emulation */
  299. static void fdctrl_reset(FDCtrl *fdctrl, int do_irq);
  300. static void fdctrl_reset_fifo(FDCtrl *fdctrl);
  301. static int fdctrl_transfer_handler (void *opaque, int nchan,
  302. int dma_pos, int dma_len);
  303. static void fdctrl_raise_irq(FDCtrl *fdctrl);
  304. static FDrive *get_cur_drv(FDCtrl *fdctrl);
  305. static uint32_t fdctrl_read_statusA(FDCtrl *fdctrl);
  306. static uint32_t fdctrl_read_statusB(FDCtrl *fdctrl);
  307. static uint32_t fdctrl_read_dor(FDCtrl *fdctrl);
  308. static void fdctrl_write_dor(FDCtrl *fdctrl, uint32_t value);
  309. static uint32_t fdctrl_read_tape(FDCtrl *fdctrl);
  310. static void fdctrl_write_tape(FDCtrl *fdctrl, uint32_t value);
  311. static uint32_t fdctrl_read_main_status(FDCtrl *fdctrl);
  312. static void fdctrl_write_rate(FDCtrl *fdctrl, uint32_t value);
  313. static uint32_t fdctrl_read_data(FDCtrl *fdctrl);
  314. static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value);
  315. static uint32_t fdctrl_read_dir(FDCtrl *fdctrl);
  316. static void fdctrl_write_ccr(FDCtrl *fdctrl, uint32_t value);
  317. enum {
  318. FD_DIR_WRITE = 0,
  319. FD_DIR_READ = 1,
  320. FD_DIR_SCANE = 2,
  321. FD_DIR_SCANL = 3,
  322. FD_DIR_SCANH = 4,
  323. FD_DIR_VERIFY = 5,
  324. };
  325. enum {
  326. FD_STATE_MULTI = 0x01, /* multi track flag */
  327. FD_STATE_FORMAT = 0x02, /* format flag */
  328. };
  329. enum {
  330. FD_REG_SRA = 0x00,
  331. FD_REG_SRB = 0x01,
  332. FD_REG_DOR = 0x02,
  333. FD_REG_TDR = 0x03,
  334. FD_REG_MSR = 0x04,
  335. FD_REG_DSR = 0x04,
  336. FD_REG_FIFO = 0x05,
  337. FD_REG_DIR = 0x07,
  338. FD_REG_CCR = 0x07,
  339. };
  340. enum {
  341. FD_CMD_READ_TRACK = 0x02,
  342. FD_CMD_SPECIFY = 0x03,
  343. FD_CMD_SENSE_DRIVE_STATUS = 0x04,
  344. FD_CMD_WRITE = 0x05,
  345. FD_CMD_READ = 0x06,
  346. FD_CMD_RECALIBRATE = 0x07,
  347. FD_CMD_SENSE_INTERRUPT_STATUS = 0x08,
  348. FD_CMD_WRITE_DELETED = 0x09,
  349. FD_CMD_READ_ID = 0x0a,
  350. FD_CMD_READ_DELETED = 0x0c,
  351. FD_CMD_FORMAT_TRACK = 0x0d,
  352. FD_CMD_DUMPREG = 0x0e,
  353. FD_CMD_SEEK = 0x0f,
  354. FD_CMD_VERSION = 0x10,
  355. FD_CMD_SCAN_EQUAL = 0x11,
  356. FD_CMD_PERPENDICULAR_MODE = 0x12,
  357. FD_CMD_CONFIGURE = 0x13,
  358. FD_CMD_LOCK = 0x14,
  359. FD_CMD_VERIFY = 0x16,
  360. FD_CMD_POWERDOWN_MODE = 0x17,
  361. FD_CMD_PART_ID = 0x18,
  362. FD_CMD_SCAN_LOW_OR_EQUAL = 0x19,
  363. FD_CMD_SCAN_HIGH_OR_EQUAL = 0x1d,
  364. FD_CMD_SAVE = 0x2e,
  365. FD_CMD_OPTION = 0x33,
  366. FD_CMD_RESTORE = 0x4e,
  367. FD_CMD_DRIVE_SPECIFICATION_COMMAND = 0x8e,
  368. FD_CMD_RELATIVE_SEEK_OUT = 0x8f,
  369. FD_CMD_FORMAT_AND_WRITE = 0xcd,
  370. FD_CMD_RELATIVE_SEEK_IN = 0xcf,
  371. };
  372. enum {
  373. FD_CONFIG_PRETRK = 0xff, /* Pre-compensation set to track 0 */
  374. FD_CONFIG_FIFOTHR = 0x0f, /* FIFO threshold set to 1 byte */
  375. FD_CONFIG_POLL = 0x10, /* Poll enabled */
  376. FD_CONFIG_EFIFO = 0x20, /* FIFO disabled */
  377. FD_CONFIG_EIS = 0x40, /* No implied seeks */
  378. };
  379. enum {
  380. FD_SR0_DS0 = 0x01,
  381. FD_SR0_DS1 = 0x02,
  382. FD_SR0_HEAD = 0x04,
  383. FD_SR0_EQPMT = 0x10,
  384. FD_SR0_SEEK = 0x20,
  385. FD_SR0_ABNTERM = 0x40,
  386. FD_SR0_INVCMD = 0x80,
  387. FD_SR0_RDYCHG = 0xc0,
  388. };
  389. enum {
  390. FD_SR1_MA = 0x01, /* Missing address mark */
  391. FD_SR1_NW = 0x02, /* Not writable */
  392. FD_SR1_EC = 0x80, /* End of cylinder */
  393. };
  394. enum {
  395. FD_SR2_SNS = 0x04, /* Scan not satisfied */
  396. FD_SR2_SEH = 0x08, /* Scan equal hit */
  397. };
  398. enum {
  399. FD_SRA_DIR = 0x01,
  400. FD_SRA_nWP = 0x02,
  401. FD_SRA_nINDX = 0x04,
  402. FD_SRA_HDSEL = 0x08,
  403. FD_SRA_nTRK0 = 0x10,
  404. FD_SRA_STEP = 0x20,
  405. FD_SRA_nDRV2 = 0x40,
  406. FD_SRA_INTPEND = 0x80,
  407. };
  408. enum {
  409. FD_SRB_MTR0 = 0x01,
  410. FD_SRB_MTR1 = 0x02,
  411. FD_SRB_WGATE = 0x04,
  412. FD_SRB_RDATA = 0x08,
  413. FD_SRB_WDATA = 0x10,
  414. FD_SRB_DR0 = 0x20,
  415. };
  416. enum {
  417. #if MAX_FD == 4
  418. FD_DOR_SELMASK = 0x03,
  419. #else
  420. FD_DOR_SELMASK = 0x01,
  421. #endif
  422. FD_DOR_nRESET = 0x04,
  423. FD_DOR_DMAEN = 0x08,
  424. FD_DOR_MOTEN0 = 0x10,
  425. FD_DOR_MOTEN1 = 0x20,
  426. FD_DOR_MOTEN2 = 0x40,
  427. FD_DOR_MOTEN3 = 0x80,
  428. };
  429. enum {
  430. #if MAX_FD == 4
  431. FD_TDR_BOOTSEL = 0x0c,
  432. #else
  433. FD_TDR_BOOTSEL = 0x04,
  434. #endif
  435. };
  436. enum {
  437. FD_DSR_DRATEMASK= 0x03,
  438. FD_DSR_PWRDOWN = 0x40,
  439. FD_DSR_SWRESET = 0x80,
  440. };
  441. enum {
  442. FD_MSR_DRV0BUSY = 0x01,
  443. FD_MSR_DRV1BUSY = 0x02,
  444. FD_MSR_DRV2BUSY = 0x04,
  445. FD_MSR_DRV3BUSY = 0x08,
  446. FD_MSR_CMDBUSY = 0x10,
  447. FD_MSR_NONDMA = 0x20,
  448. FD_MSR_DIO = 0x40,
  449. FD_MSR_RQM = 0x80,
  450. };
  451. enum {
  452. FD_DIR_DSKCHG = 0x80,
  453. };
  454. #define FD_MULTI_TRACK(state) ((state) & FD_STATE_MULTI)
  455. #define FD_FORMAT_CMD(state) ((state) & FD_STATE_FORMAT)
  456. struct FDCtrl {
  457. MemoryRegion iomem;
  458. qemu_irq irq;
  459. /* Controller state */
  460. QEMUTimer *result_timer;
  461. int dma_chann;
  462. /* Controller's identification */
  463. uint8_t version;
  464. /* HW */
  465. uint8_t sra;
  466. uint8_t srb;
  467. uint8_t dor;
  468. uint8_t dor_vmstate; /* only used as temp during vmstate */
  469. uint8_t tdr;
  470. uint8_t dsr;
  471. uint8_t msr;
  472. uint8_t cur_drv;
  473. uint8_t status0;
  474. uint8_t status1;
  475. uint8_t status2;
  476. /* Command FIFO */
  477. uint8_t *fifo;
  478. int32_t fifo_size;
  479. uint32_t data_pos;
  480. uint32_t data_len;
  481. uint8_t data_state;
  482. uint8_t data_dir;
  483. uint8_t eot; /* last wanted sector */
  484. /* States kept only to be returned back */
  485. /* precompensation */
  486. uint8_t precomp_trk;
  487. uint8_t config;
  488. uint8_t lock;
  489. /* Power down config (also with status regB access mode */
  490. uint8_t pwrd;
  491. /* Floppy drives */
  492. uint8_t num_floppies;
  493. /* Sun4m quirks? */
  494. int sun4m;
  495. FDrive drives[MAX_FD];
  496. int reset_sensei;
  497. uint32_t check_media_rate;
  498. /* Timers state */
  499. uint8_t timer0;
  500. uint8_t timer1;
  501. };
  502. typedef struct FDCtrlSysBus {
  503. SysBusDevice busdev;
  504. struct FDCtrl state;
  505. } FDCtrlSysBus;
  506. typedef struct FDCtrlISABus {
  507. ISADevice busdev;
  508. uint32_t iobase;
  509. uint32_t irq;
  510. uint32_t dma;
  511. struct FDCtrl state;
  512. int32_t bootindexA;
  513. int32_t bootindexB;
  514. } FDCtrlISABus;
  515. static uint32_t fdctrl_read (void *opaque, uint32_t reg)
  516. {
  517. FDCtrl *fdctrl = opaque;
  518. uint32_t retval;
  519. reg &= 7;
  520. switch (reg) {
  521. case FD_REG_SRA:
  522. retval = fdctrl_read_statusA(fdctrl);
  523. break;
  524. case FD_REG_SRB:
  525. retval = fdctrl_read_statusB(fdctrl);
  526. break;
  527. case FD_REG_DOR:
  528. retval = fdctrl_read_dor(fdctrl);
  529. break;
  530. case FD_REG_TDR:
  531. retval = fdctrl_read_tape(fdctrl);
  532. break;
  533. case FD_REG_MSR:
  534. retval = fdctrl_read_main_status(fdctrl);
  535. break;
  536. case FD_REG_FIFO:
  537. retval = fdctrl_read_data(fdctrl);
  538. break;
  539. case FD_REG_DIR:
  540. retval = fdctrl_read_dir(fdctrl);
  541. break;
  542. default:
  543. retval = (uint32_t)(-1);
  544. break;
  545. }
  546. FLOPPY_DPRINTF("read reg%d: 0x%02x\n", reg & 7, retval);
  547. return retval;
  548. }
  549. static void fdctrl_write (void *opaque, uint32_t reg, uint32_t value)
  550. {
  551. FDCtrl *fdctrl = opaque;
  552. FLOPPY_DPRINTF("write reg%d: 0x%02x\n", reg & 7, value);
  553. reg &= 7;
  554. switch (reg) {
  555. case FD_REG_DOR:
  556. fdctrl_write_dor(fdctrl, value);
  557. break;
  558. case FD_REG_TDR:
  559. fdctrl_write_tape(fdctrl, value);
  560. break;
  561. case FD_REG_DSR:
  562. fdctrl_write_rate(fdctrl, value);
  563. break;
  564. case FD_REG_FIFO:
  565. fdctrl_write_data(fdctrl, value);
  566. break;
  567. case FD_REG_CCR:
  568. fdctrl_write_ccr(fdctrl, value);
  569. break;
  570. default:
  571. break;
  572. }
  573. }
  574. static uint64_t fdctrl_read_mem (void *opaque, hwaddr reg,
  575. unsigned ize)
  576. {
  577. return fdctrl_read(opaque, (uint32_t)reg);
  578. }
  579. static void fdctrl_write_mem (void *opaque, hwaddr reg,
  580. uint64_t value, unsigned size)
  581. {
  582. fdctrl_write(opaque, (uint32_t)reg, value);
  583. }
  584. static const MemoryRegionOps fdctrl_mem_ops = {
  585. .read = fdctrl_read_mem,
  586. .write = fdctrl_write_mem,
  587. .endianness = DEVICE_NATIVE_ENDIAN,
  588. };
  589. static const MemoryRegionOps fdctrl_mem_strict_ops = {
  590. .read = fdctrl_read_mem,
  591. .write = fdctrl_write_mem,
  592. .endianness = DEVICE_NATIVE_ENDIAN,
  593. .valid = {
  594. .min_access_size = 1,
  595. .max_access_size = 1,
  596. },
  597. };
  598. static bool fdrive_media_changed_needed(void *opaque)
  599. {
  600. FDrive *drive = opaque;
  601. return (drive->bs != NULL && drive->media_changed != 1);
  602. }
  603. static const VMStateDescription vmstate_fdrive_media_changed = {
  604. .name = "fdrive/media_changed",
  605. .version_id = 1,
  606. .minimum_version_id = 1,
  607. .minimum_version_id_old = 1,
  608. .fields = (VMStateField[]) {
  609. VMSTATE_UINT8(media_changed, FDrive),
  610. VMSTATE_END_OF_LIST()
  611. }
  612. };
  613. static bool fdrive_media_rate_needed(void *opaque)
  614. {
  615. FDrive *drive = opaque;
  616. return drive->fdctrl->check_media_rate;
  617. }
  618. static const VMStateDescription vmstate_fdrive_media_rate = {
  619. .name = "fdrive/media_rate",
  620. .version_id = 1,
  621. .minimum_version_id = 1,
  622. .minimum_version_id_old = 1,
  623. .fields = (VMStateField[]) {
  624. VMSTATE_UINT8(media_rate, FDrive),
  625. VMSTATE_END_OF_LIST()
  626. }
  627. };
  628. static const VMStateDescription vmstate_fdrive = {
  629. .name = "fdrive",
  630. .version_id = 1,
  631. .minimum_version_id = 1,
  632. .minimum_version_id_old = 1,
  633. .fields = (VMStateField[]) {
  634. VMSTATE_UINT8(head, FDrive),
  635. VMSTATE_UINT8(track, FDrive),
  636. VMSTATE_UINT8(sect, FDrive),
  637. VMSTATE_END_OF_LIST()
  638. },
  639. .subsections = (VMStateSubsection[]) {
  640. {
  641. .vmsd = &vmstate_fdrive_media_changed,
  642. .needed = &fdrive_media_changed_needed,
  643. } , {
  644. .vmsd = &vmstate_fdrive_media_rate,
  645. .needed = &fdrive_media_rate_needed,
  646. } , {
  647. /* empty */
  648. }
  649. }
  650. };
  651. static void fdc_pre_save(void *opaque)
  652. {
  653. FDCtrl *s = opaque;
  654. s->dor_vmstate = s->dor | GET_CUR_DRV(s);
  655. }
  656. static int fdc_post_load(void *opaque, int version_id)
  657. {
  658. FDCtrl *s = opaque;
  659. SET_CUR_DRV(s, s->dor_vmstate & FD_DOR_SELMASK);
  660. s->dor = s->dor_vmstate & ~FD_DOR_SELMASK;
  661. return 0;
  662. }
  663. static const VMStateDescription vmstate_fdc = {
  664. .name = "fdc",
  665. .version_id = 2,
  666. .minimum_version_id = 2,
  667. .minimum_version_id_old = 2,
  668. .pre_save = fdc_pre_save,
  669. .post_load = fdc_post_load,
  670. .fields = (VMStateField []) {
  671. /* Controller State */
  672. VMSTATE_UINT8(sra, FDCtrl),
  673. VMSTATE_UINT8(srb, FDCtrl),
  674. VMSTATE_UINT8(dor_vmstate, FDCtrl),
  675. VMSTATE_UINT8(tdr, FDCtrl),
  676. VMSTATE_UINT8(dsr, FDCtrl),
  677. VMSTATE_UINT8(msr, FDCtrl),
  678. VMSTATE_UINT8(status0, FDCtrl),
  679. VMSTATE_UINT8(status1, FDCtrl),
  680. VMSTATE_UINT8(status2, FDCtrl),
  681. /* Command FIFO */
  682. VMSTATE_VARRAY_INT32(fifo, FDCtrl, fifo_size, 0, vmstate_info_uint8,
  683. uint8_t),
  684. VMSTATE_UINT32(data_pos, FDCtrl),
  685. VMSTATE_UINT32(data_len, FDCtrl),
  686. VMSTATE_UINT8(data_state, FDCtrl),
  687. VMSTATE_UINT8(data_dir, FDCtrl),
  688. VMSTATE_UINT8(eot, FDCtrl),
  689. /* States kept only to be returned back */
  690. VMSTATE_UINT8(timer0, FDCtrl),
  691. VMSTATE_UINT8(timer1, FDCtrl),
  692. VMSTATE_UINT8(precomp_trk, FDCtrl),
  693. VMSTATE_UINT8(config, FDCtrl),
  694. VMSTATE_UINT8(lock, FDCtrl),
  695. VMSTATE_UINT8(pwrd, FDCtrl),
  696. VMSTATE_UINT8_EQUAL(num_floppies, FDCtrl),
  697. VMSTATE_STRUCT_ARRAY(drives, FDCtrl, MAX_FD, 1,
  698. vmstate_fdrive, FDrive),
  699. VMSTATE_END_OF_LIST()
  700. }
  701. };
  702. static void fdctrl_external_reset_sysbus(DeviceState *d)
  703. {
  704. FDCtrlSysBus *sys = container_of(d, FDCtrlSysBus, busdev.qdev);
  705. FDCtrl *s = &sys->state;
  706. fdctrl_reset(s, 0);
  707. }
  708. static void fdctrl_external_reset_isa(DeviceState *d)
  709. {
  710. FDCtrlISABus *isa = container_of(d, FDCtrlISABus, busdev.qdev);
  711. FDCtrl *s = &isa->state;
  712. fdctrl_reset(s, 0);
  713. }
  714. static void fdctrl_handle_tc(void *opaque, int irq, int level)
  715. {
  716. //FDCtrl *s = opaque;
  717. if (level) {
  718. // XXX
  719. FLOPPY_DPRINTF("TC pulsed\n");
  720. }
  721. }
  722. /* Change IRQ state */
  723. static void fdctrl_reset_irq(FDCtrl *fdctrl)
  724. {
  725. fdctrl->status0 = 0;
  726. if (!(fdctrl->sra & FD_SRA_INTPEND))
  727. return;
  728. FLOPPY_DPRINTF("Reset interrupt\n");
  729. qemu_set_irq(fdctrl->irq, 0);
  730. fdctrl->sra &= ~FD_SRA_INTPEND;
  731. }
  732. static void fdctrl_raise_irq(FDCtrl *fdctrl)
  733. {
  734. /* Sparc mutation */
  735. if (fdctrl->sun4m && (fdctrl->msr & FD_MSR_CMDBUSY)) {
  736. /* XXX: not sure */
  737. fdctrl->msr &= ~FD_MSR_CMDBUSY;
  738. fdctrl->msr |= FD_MSR_RQM | FD_MSR_DIO;
  739. return;
  740. }
  741. if (!(fdctrl->sra & FD_SRA_INTPEND)) {
  742. qemu_set_irq(fdctrl->irq, 1);
  743. fdctrl->sra |= FD_SRA_INTPEND;
  744. }
  745. fdctrl->reset_sensei = 0;
  746. FLOPPY_DPRINTF("Set interrupt status to 0x%02x\n", fdctrl->status0);
  747. }
  748. /* Reset controller */
  749. static void fdctrl_reset(FDCtrl *fdctrl, int do_irq)
  750. {
  751. int i;
  752. FLOPPY_DPRINTF("reset controller\n");
  753. fdctrl_reset_irq(fdctrl);
  754. /* Initialise controller */
  755. fdctrl->sra = 0;
  756. fdctrl->srb = 0xc0;
  757. if (!fdctrl->drives[1].bs)
  758. fdctrl->sra |= FD_SRA_nDRV2;
  759. fdctrl->cur_drv = 0;
  760. fdctrl->dor = FD_DOR_nRESET;
  761. fdctrl->dor |= (fdctrl->dma_chann != -1) ? FD_DOR_DMAEN : 0;
  762. fdctrl->msr = FD_MSR_RQM;
  763. /* FIFO state */
  764. fdctrl->data_pos = 0;
  765. fdctrl->data_len = 0;
  766. fdctrl->data_state = 0;
  767. fdctrl->data_dir = FD_DIR_WRITE;
  768. for (i = 0; i < MAX_FD; i++)
  769. fd_recalibrate(&fdctrl->drives[i]);
  770. fdctrl_reset_fifo(fdctrl);
  771. if (do_irq) {
  772. fdctrl->status0 |= FD_SR0_RDYCHG;
  773. fdctrl_raise_irq(fdctrl);
  774. fdctrl->reset_sensei = FD_RESET_SENSEI_COUNT;
  775. }
  776. }
  777. static inline FDrive *drv0(FDCtrl *fdctrl)
  778. {
  779. return &fdctrl->drives[(fdctrl->tdr & FD_TDR_BOOTSEL) >> 2];
  780. }
  781. static inline FDrive *drv1(FDCtrl *fdctrl)
  782. {
  783. if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (1 << 2))
  784. return &fdctrl->drives[1];
  785. else
  786. return &fdctrl->drives[0];
  787. }
  788. #if MAX_FD == 4
  789. static inline FDrive *drv2(FDCtrl *fdctrl)
  790. {
  791. if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (2 << 2))
  792. return &fdctrl->drives[2];
  793. else
  794. return &fdctrl->drives[1];
  795. }
  796. static inline FDrive *drv3(FDCtrl *fdctrl)
  797. {
  798. if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (3 << 2))
  799. return &fdctrl->drives[3];
  800. else
  801. return &fdctrl->drives[2];
  802. }
  803. #endif
  804. static FDrive *get_cur_drv(FDCtrl *fdctrl)
  805. {
  806. switch (fdctrl->cur_drv) {
  807. case 0: return drv0(fdctrl);
  808. case 1: return drv1(fdctrl);
  809. #if MAX_FD == 4
  810. case 2: return drv2(fdctrl);
  811. case 3: return drv3(fdctrl);
  812. #endif
  813. default: return NULL;
  814. }
  815. }
  816. /* Status A register : 0x00 (read-only) */
  817. static uint32_t fdctrl_read_statusA(FDCtrl *fdctrl)
  818. {
  819. uint32_t retval = fdctrl->sra;
  820. FLOPPY_DPRINTF("status register A: 0x%02x\n", retval);
  821. return retval;
  822. }
  823. /* Status B register : 0x01 (read-only) */
  824. static uint32_t fdctrl_read_statusB(FDCtrl *fdctrl)
  825. {
  826. uint32_t retval = fdctrl->srb;
  827. FLOPPY_DPRINTF("status register B: 0x%02x\n", retval);
  828. return retval;
  829. }
  830. /* Digital output register : 0x02 */
  831. static uint32_t fdctrl_read_dor(FDCtrl *fdctrl)
  832. {
  833. uint32_t retval = fdctrl->dor;
  834. /* Selected drive */
  835. retval |= fdctrl->cur_drv;
  836. FLOPPY_DPRINTF("digital output register: 0x%02x\n", retval);
  837. return retval;
  838. }
  839. static void fdctrl_write_dor(FDCtrl *fdctrl, uint32_t value)
  840. {
  841. FLOPPY_DPRINTF("digital output register set to 0x%02x\n", value);
  842. /* Motors */
  843. if (value & FD_DOR_MOTEN0)
  844. fdctrl->srb |= FD_SRB_MTR0;
  845. else
  846. fdctrl->srb &= ~FD_SRB_MTR0;
  847. if (value & FD_DOR_MOTEN1)
  848. fdctrl->srb |= FD_SRB_MTR1;
  849. else
  850. fdctrl->srb &= ~FD_SRB_MTR1;
  851. /* Drive */
  852. if (value & 1)
  853. fdctrl->srb |= FD_SRB_DR0;
  854. else
  855. fdctrl->srb &= ~FD_SRB_DR0;
  856. /* Reset */
  857. if (!(value & FD_DOR_nRESET)) {
  858. if (fdctrl->dor & FD_DOR_nRESET) {
  859. FLOPPY_DPRINTF("controller enter RESET state\n");
  860. }
  861. } else {
  862. if (!(fdctrl->dor & FD_DOR_nRESET)) {
  863. FLOPPY_DPRINTF("controller out of RESET state\n");
  864. fdctrl_reset(fdctrl, 1);
  865. fdctrl->dsr &= ~FD_DSR_PWRDOWN;
  866. }
  867. }
  868. /* Selected drive */
  869. fdctrl->cur_drv = value & FD_DOR_SELMASK;
  870. fdctrl->dor = value;
  871. }
  872. /* Tape drive register : 0x03 */
  873. static uint32_t fdctrl_read_tape(FDCtrl *fdctrl)
  874. {
  875. uint32_t retval = fdctrl->tdr;
  876. FLOPPY_DPRINTF("tape drive register: 0x%02x\n", retval);
  877. return retval;
  878. }
  879. static void fdctrl_write_tape(FDCtrl *fdctrl, uint32_t value)
  880. {
  881. /* Reset mode */
  882. if (!(fdctrl->dor & FD_DOR_nRESET)) {
  883. FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
  884. return;
  885. }
  886. FLOPPY_DPRINTF("tape drive register set to 0x%02x\n", value);
  887. /* Disk boot selection indicator */
  888. fdctrl->tdr = value & FD_TDR_BOOTSEL;
  889. /* Tape indicators: never allow */
  890. }
  891. /* Main status register : 0x04 (read) */
  892. static uint32_t fdctrl_read_main_status(FDCtrl *fdctrl)
  893. {
  894. uint32_t retval = fdctrl->msr;
  895. fdctrl->dsr &= ~FD_DSR_PWRDOWN;
  896. fdctrl->dor |= FD_DOR_nRESET;
  897. /* Sparc mutation */
  898. if (fdctrl->sun4m) {
  899. retval |= FD_MSR_DIO;
  900. fdctrl_reset_irq(fdctrl);
  901. };
  902. FLOPPY_DPRINTF("main status register: 0x%02x\n", retval);
  903. return retval;
  904. }
  905. /* Data select rate register : 0x04 (write) */
  906. static void fdctrl_write_rate(FDCtrl *fdctrl, uint32_t value)
  907. {
  908. /* Reset mode */
  909. if (!(fdctrl->dor & FD_DOR_nRESET)) {
  910. FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
  911. return;
  912. }
  913. FLOPPY_DPRINTF("select rate register set to 0x%02x\n", value);
  914. /* Reset: autoclear */
  915. if (value & FD_DSR_SWRESET) {
  916. fdctrl->dor &= ~FD_DOR_nRESET;
  917. fdctrl_reset(fdctrl, 1);
  918. fdctrl->dor |= FD_DOR_nRESET;
  919. }
  920. if (value & FD_DSR_PWRDOWN) {
  921. fdctrl_reset(fdctrl, 1);
  922. }
  923. fdctrl->dsr = value;
  924. }
  925. /* Configuration control register: 0x07 (write) */
  926. static void fdctrl_write_ccr(FDCtrl *fdctrl, uint32_t value)
  927. {
  928. /* Reset mode */
  929. if (!(fdctrl->dor & FD_DOR_nRESET)) {
  930. FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
  931. return;
  932. }
  933. FLOPPY_DPRINTF("configuration control register set to 0x%02x\n", value);
  934. /* Only the rate selection bits used in AT mode, and we
  935. * store those in the DSR.
  936. */
  937. fdctrl->dsr = (fdctrl->dsr & ~FD_DSR_DRATEMASK) |
  938. (value & FD_DSR_DRATEMASK);
  939. }
  940. static int fdctrl_media_changed(FDrive *drv)
  941. {
  942. return drv->media_changed;
  943. }
  944. /* Digital input register : 0x07 (read-only) */
  945. static uint32_t fdctrl_read_dir(FDCtrl *fdctrl)
  946. {
  947. uint32_t retval = 0;
  948. if (fdctrl_media_changed(get_cur_drv(fdctrl))) {
  949. retval |= FD_DIR_DSKCHG;
  950. }
  951. if (retval != 0) {
  952. FLOPPY_DPRINTF("Floppy digital input register: 0x%02x\n", retval);
  953. }
  954. return retval;
  955. }
  956. /* FIFO state control */
  957. static void fdctrl_reset_fifo(FDCtrl *fdctrl)
  958. {
  959. fdctrl->data_dir = FD_DIR_WRITE;
  960. fdctrl->data_pos = 0;
  961. fdctrl->msr &= ~(FD_MSR_CMDBUSY | FD_MSR_DIO);
  962. }
  963. /* Set FIFO status for the host to read */
  964. static void fdctrl_set_fifo(FDCtrl *fdctrl, int fifo_len)
  965. {
  966. fdctrl->data_dir = FD_DIR_READ;
  967. fdctrl->data_len = fifo_len;
  968. fdctrl->data_pos = 0;
  969. fdctrl->msr |= FD_MSR_CMDBUSY | FD_MSR_RQM | FD_MSR_DIO;
  970. }
  971. /* Set an error: unimplemented/unknown command */
  972. static void fdctrl_unimplemented(FDCtrl *fdctrl, int direction)
  973. {
  974. qemu_log_mask(LOG_UNIMP, "fdc: unimplemented command 0x%02x\n",
  975. fdctrl->fifo[0]);
  976. fdctrl->fifo[0] = FD_SR0_INVCMD;
  977. fdctrl_set_fifo(fdctrl, 1);
  978. }
  979. /* Seek to next sector
  980. * returns 0 when end of track reached (for DBL_SIDES on head 1)
  981. * otherwise returns 1
  982. */
  983. static int fdctrl_seek_to_next_sect(FDCtrl *fdctrl, FDrive *cur_drv)
  984. {
  985. FLOPPY_DPRINTF("seek to next sector (%d %02x %02x => %d)\n",
  986. cur_drv->head, cur_drv->track, cur_drv->sect,
  987. fd_sector(cur_drv));
  988. /* XXX: cur_drv->sect >= cur_drv->last_sect should be an
  989. error in fact */
  990. uint8_t new_head = cur_drv->head;
  991. uint8_t new_track = cur_drv->track;
  992. uint8_t new_sect = cur_drv->sect;
  993. int ret = 1;
  994. if (new_sect >= cur_drv->last_sect ||
  995. new_sect == fdctrl->eot) {
  996. new_sect = 1;
  997. if (FD_MULTI_TRACK(fdctrl->data_state)) {
  998. if (new_head == 0 &&
  999. (cur_drv->flags & FDISK_DBL_SIDES) != 0) {
  1000. new_head = 1;
  1001. } else {
  1002. new_head = 0;
  1003. new_track++;
  1004. fdctrl->status0 |= FD_SR0_SEEK;
  1005. if ((cur_drv->flags & FDISK_DBL_SIDES) == 0) {
  1006. ret = 0;
  1007. }
  1008. }
  1009. } else {
  1010. fdctrl->status0 |= FD_SR0_SEEK;
  1011. new_track++;
  1012. ret = 0;
  1013. }
  1014. if (ret == 1) {
  1015. FLOPPY_DPRINTF("seek to next track (%d %02x %02x => %d)\n",
  1016. new_head, new_track, new_sect, fd_sector(cur_drv));
  1017. }
  1018. } else {
  1019. new_sect++;
  1020. }
  1021. fd_seek(cur_drv, new_head, new_track, new_sect, 1);
  1022. return ret;
  1023. }
  1024. /* Callback for transfer end (stop or abort) */
  1025. static void fdctrl_stop_transfer(FDCtrl *fdctrl, uint8_t status0,
  1026. uint8_t status1, uint8_t status2)
  1027. {
  1028. FDrive *cur_drv;
  1029. cur_drv = get_cur_drv(fdctrl);
  1030. fdctrl->status0 &= ~(FD_SR0_DS0 | FD_SR0_DS1 | FD_SR0_HEAD);
  1031. fdctrl->status0 |= GET_CUR_DRV(fdctrl);
  1032. if (cur_drv->head) {
  1033. fdctrl->status0 |= FD_SR0_HEAD;
  1034. }
  1035. fdctrl->status0 |= status0;
  1036. FLOPPY_DPRINTF("transfer status: %02x %02x %02x (%02x)\n",
  1037. status0, status1, status2, fdctrl->status0);
  1038. fdctrl->fifo[0] = fdctrl->status0;
  1039. fdctrl->fifo[1] = status1;
  1040. fdctrl->fifo[2] = status2;
  1041. fdctrl->fifo[3] = cur_drv->track;
  1042. fdctrl->fifo[4] = cur_drv->head;
  1043. fdctrl->fifo[5] = cur_drv->sect;
  1044. fdctrl->fifo[6] = FD_SECTOR_SC;
  1045. fdctrl->data_dir = FD_DIR_READ;
  1046. if (!(fdctrl->msr & FD_MSR_NONDMA)) {
  1047. DMA_release_DREQ(fdctrl->dma_chann);
  1048. }
  1049. fdctrl->msr |= FD_MSR_RQM | FD_MSR_DIO;
  1050. fdctrl->msr &= ~FD_MSR_NONDMA;
  1051. fdctrl_set_fifo(fdctrl, 7);
  1052. fdctrl_raise_irq(fdctrl);
  1053. }
  1054. /* Prepare a data transfer (either DMA or FIFO) */
  1055. static void fdctrl_start_transfer(FDCtrl *fdctrl, int direction)
  1056. {
  1057. FDrive *cur_drv;
  1058. uint8_t kh, kt, ks;
  1059. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1060. cur_drv = get_cur_drv(fdctrl);
  1061. kt = fdctrl->fifo[2];
  1062. kh = fdctrl->fifo[3];
  1063. ks = fdctrl->fifo[4];
  1064. FLOPPY_DPRINTF("Start transfer at %d %d %02x %02x (%d)\n",
  1065. GET_CUR_DRV(fdctrl), kh, kt, ks,
  1066. fd_sector_calc(kh, kt, ks, cur_drv->last_sect,
  1067. NUM_SIDES(cur_drv)));
  1068. switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & FD_CONFIG_EIS)) {
  1069. case 2:
  1070. /* sect too big */
  1071. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
  1072. fdctrl->fifo[3] = kt;
  1073. fdctrl->fifo[4] = kh;
  1074. fdctrl->fifo[5] = ks;
  1075. return;
  1076. case 3:
  1077. /* track too big */
  1078. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_EC, 0x00);
  1079. fdctrl->fifo[3] = kt;
  1080. fdctrl->fifo[4] = kh;
  1081. fdctrl->fifo[5] = ks;
  1082. return;
  1083. case 4:
  1084. /* No seek enabled */
  1085. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
  1086. fdctrl->fifo[3] = kt;
  1087. fdctrl->fifo[4] = kh;
  1088. fdctrl->fifo[5] = ks;
  1089. return;
  1090. case 1:
  1091. fdctrl->status0 |= FD_SR0_SEEK;
  1092. break;
  1093. default:
  1094. break;
  1095. }
  1096. /* Check the data rate. If the programmed data rate does not match
  1097. * the currently inserted medium, the operation has to fail. */
  1098. if (fdctrl->check_media_rate &&
  1099. (fdctrl->dsr & FD_DSR_DRATEMASK) != cur_drv->media_rate) {
  1100. FLOPPY_DPRINTF("data rate mismatch (fdc=%d, media=%d)\n",
  1101. fdctrl->dsr & FD_DSR_DRATEMASK, cur_drv->media_rate);
  1102. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA, 0x00);
  1103. fdctrl->fifo[3] = kt;
  1104. fdctrl->fifo[4] = kh;
  1105. fdctrl->fifo[5] = ks;
  1106. return;
  1107. }
  1108. /* Set the FIFO state */
  1109. fdctrl->data_dir = direction;
  1110. fdctrl->data_pos = 0;
  1111. assert(fdctrl->msr & FD_MSR_CMDBUSY);
  1112. if (fdctrl->fifo[0] & 0x80)
  1113. fdctrl->data_state |= FD_STATE_MULTI;
  1114. else
  1115. fdctrl->data_state &= ~FD_STATE_MULTI;
  1116. if (fdctrl->fifo[5] == 0) {
  1117. fdctrl->data_len = fdctrl->fifo[8];
  1118. } else {
  1119. int tmp;
  1120. fdctrl->data_len = 128 << (fdctrl->fifo[5] > 7 ? 7 : fdctrl->fifo[5]);
  1121. tmp = (fdctrl->fifo[6] - ks + 1);
  1122. if (fdctrl->fifo[0] & 0x80)
  1123. tmp += fdctrl->fifo[6];
  1124. fdctrl->data_len *= tmp;
  1125. }
  1126. fdctrl->eot = fdctrl->fifo[6];
  1127. if (fdctrl->dor & FD_DOR_DMAEN) {
  1128. int dma_mode;
  1129. /* DMA transfer are enabled. Check if DMA channel is well programmed */
  1130. dma_mode = DMA_get_channel_mode(fdctrl->dma_chann);
  1131. dma_mode = (dma_mode >> 2) & 3;
  1132. FLOPPY_DPRINTF("dma_mode=%d direction=%d (%d - %d)\n",
  1133. dma_mode, direction,
  1134. (128 << fdctrl->fifo[5]) *
  1135. (cur_drv->last_sect - ks + 1), fdctrl->data_len);
  1136. if (((direction == FD_DIR_SCANE || direction == FD_DIR_SCANL ||
  1137. direction == FD_DIR_SCANH) && dma_mode == 0) ||
  1138. (direction == FD_DIR_WRITE && dma_mode == 2) ||
  1139. (direction == FD_DIR_READ && dma_mode == 1) ||
  1140. (direction == FD_DIR_VERIFY)) {
  1141. /* No access is allowed until DMA transfer has completed */
  1142. fdctrl->msr &= ~FD_MSR_RQM;
  1143. if (direction != FD_DIR_VERIFY) {
  1144. /* Now, we just have to wait for the DMA controller to
  1145. * recall us...
  1146. */
  1147. DMA_hold_DREQ(fdctrl->dma_chann);
  1148. DMA_schedule(fdctrl->dma_chann);
  1149. } else {
  1150. /* Start transfer */
  1151. fdctrl_transfer_handler(fdctrl, fdctrl->dma_chann, 0,
  1152. fdctrl->data_len);
  1153. }
  1154. return;
  1155. } else {
  1156. FLOPPY_DPRINTF("bad dma_mode=%d direction=%d\n", dma_mode,
  1157. direction);
  1158. }
  1159. }
  1160. FLOPPY_DPRINTF("start non-DMA transfer\n");
  1161. fdctrl->msr |= FD_MSR_NONDMA;
  1162. if (direction != FD_DIR_WRITE)
  1163. fdctrl->msr |= FD_MSR_DIO;
  1164. /* IO based transfer: calculate len */
  1165. fdctrl_raise_irq(fdctrl);
  1166. }
  1167. /* Prepare a transfer of deleted data */
  1168. static void fdctrl_start_transfer_del(FDCtrl *fdctrl, int direction)
  1169. {
  1170. qemu_log_mask(LOG_UNIMP, "fdctrl_start_transfer_del() unimplemented\n");
  1171. /* We don't handle deleted data,
  1172. * so we don't return *ANYTHING*
  1173. */
  1174. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
  1175. }
  1176. /* handlers for DMA transfers */
  1177. static int fdctrl_transfer_handler (void *opaque, int nchan,
  1178. int dma_pos, int dma_len)
  1179. {
  1180. FDCtrl *fdctrl;
  1181. FDrive *cur_drv;
  1182. int len, start_pos, rel_pos;
  1183. uint8_t status0 = 0x00, status1 = 0x00, status2 = 0x00;
  1184. fdctrl = opaque;
  1185. if (fdctrl->msr & FD_MSR_RQM) {
  1186. FLOPPY_DPRINTF("Not in DMA transfer mode !\n");
  1187. return 0;
  1188. }
  1189. cur_drv = get_cur_drv(fdctrl);
  1190. if (fdctrl->data_dir == FD_DIR_SCANE || fdctrl->data_dir == FD_DIR_SCANL ||
  1191. fdctrl->data_dir == FD_DIR_SCANH)
  1192. status2 = FD_SR2_SNS;
  1193. if (dma_len > fdctrl->data_len)
  1194. dma_len = fdctrl->data_len;
  1195. if (cur_drv->bs == NULL) {
  1196. if (fdctrl->data_dir == FD_DIR_WRITE)
  1197. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
  1198. else
  1199. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
  1200. len = 0;
  1201. goto transfer_error;
  1202. }
  1203. rel_pos = fdctrl->data_pos % FD_SECTOR_LEN;
  1204. for (start_pos = fdctrl->data_pos; fdctrl->data_pos < dma_len;) {
  1205. len = dma_len - fdctrl->data_pos;
  1206. if (len + rel_pos > FD_SECTOR_LEN)
  1207. len = FD_SECTOR_LEN - rel_pos;
  1208. FLOPPY_DPRINTF("copy %d bytes (%d %d %d) %d pos %d %02x "
  1209. "(%d-0x%08x 0x%08x)\n", len, dma_len, fdctrl->data_pos,
  1210. fdctrl->data_len, GET_CUR_DRV(fdctrl), cur_drv->head,
  1211. cur_drv->track, cur_drv->sect, fd_sector(cur_drv),
  1212. fd_sector(cur_drv) * FD_SECTOR_LEN);
  1213. if (fdctrl->data_dir != FD_DIR_WRITE ||
  1214. len < FD_SECTOR_LEN || rel_pos != 0) {
  1215. /* READ & SCAN commands and realign to a sector for WRITE */
  1216. if (bdrv_read(cur_drv->bs, fd_sector(cur_drv),
  1217. fdctrl->fifo, 1) < 0) {
  1218. FLOPPY_DPRINTF("Floppy: error getting sector %d\n",
  1219. fd_sector(cur_drv));
  1220. /* Sure, image size is too small... */
  1221. memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
  1222. }
  1223. }
  1224. switch (fdctrl->data_dir) {
  1225. case FD_DIR_READ:
  1226. /* READ commands */
  1227. DMA_write_memory (nchan, fdctrl->fifo + rel_pos,
  1228. fdctrl->data_pos, len);
  1229. break;
  1230. case FD_DIR_WRITE:
  1231. /* WRITE commands */
  1232. if (cur_drv->ro) {
  1233. /* Handle readonly medium early, no need to do DMA, touch the
  1234. * LED or attempt any writes. A real floppy doesn't attempt
  1235. * to write to readonly media either. */
  1236. fdctrl_stop_transfer(fdctrl,
  1237. FD_SR0_ABNTERM | FD_SR0_SEEK, FD_SR1_NW,
  1238. 0x00);
  1239. goto transfer_error;
  1240. }
  1241. DMA_read_memory (nchan, fdctrl->fifo + rel_pos,
  1242. fdctrl->data_pos, len);
  1243. if (bdrv_write(cur_drv->bs, fd_sector(cur_drv),
  1244. fdctrl->fifo, 1) < 0) {
  1245. FLOPPY_DPRINTF("error writing sector %d\n",
  1246. fd_sector(cur_drv));
  1247. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
  1248. goto transfer_error;
  1249. }
  1250. break;
  1251. case FD_DIR_VERIFY:
  1252. /* VERIFY commands */
  1253. break;
  1254. default:
  1255. /* SCAN commands */
  1256. {
  1257. uint8_t tmpbuf[FD_SECTOR_LEN];
  1258. int ret;
  1259. DMA_read_memory (nchan, tmpbuf, fdctrl->data_pos, len);
  1260. ret = memcmp(tmpbuf, fdctrl->fifo + rel_pos, len);
  1261. if (ret == 0) {
  1262. status2 = FD_SR2_SEH;
  1263. goto end_transfer;
  1264. }
  1265. if ((ret < 0 && fdctrl->data_dir == FD_DIR_SCANL) ||
  1266. (ret > 0 && fdctrl->data_dir == FD_DIR_SCANH)) {
  1267. status2 = 0x00;
  1268. goto end_transfer;
  1269. }
  1270. }
  1271. break;
  1272. }
  1273. fdctrl->data_pos += len;
  1274. rel_pos = fdctrl->data_pos % FD_SECTOR_LEN;
  1275. if (rel_pos == 0) {
  1276. /* Seek to next sector */
  1277. if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv))
  1278. break;
  1279. }
  1280. }
  1281. end_transfer:
  1282. len = fdctrl->data_pos - start_pos;
  1283. FLOPPY_DPRINTF("end transfer %d %d %d\n",
  1284. fdctrl->data_pos, len, fdctrl->data_len);
  1285. if (fdctrl->data_dir == FD_DIR_SCANE ||
  1286. fdctrl->data_dir == FD_DIR_SCANL ||
  1287. fdctrl->data_dir == FD_DIR_SCANH)
  1288. status2 = FD_SR2_SEH;
  1289. fdctrl->data_len -= len;
  1290. fdctrl_stop_transfer(fdctrl, status0, status1, status2);
  1291. transfer_error:
  1292. return len;
  1293. }
  1294. /* Data register : 0x05 */
  1295. static uint32_t fdctrl_read_data(FDCtrl *fdctrl)
  1296. {
  1297. FDrive *cur_drv;
  1298. uint32_t retval = 0;
  1299. int pos;
  1300. cur_drv = get_cur_drv(fdctrl);
  1301. fdctrl->dsr &= ~FD_DSR_PWRDOWN;
  1302. if (!(fdctrl->msr & FD_MSR_RQM) || !(fdctrl->msr & FD_MSR_DIO)) {
  1303. FLOPPY_DPRINTF("error: controller not ready for reading\n");
  1304. return 0;
  1305. }
  1306. pos = fdctrl->data_pos;
  1307. if (fdctrl->msr & FD_MSR_NONDMA) {
  1308. pos %= FD_SECTOR_LEN;
  1309. if (pos == 0) {
  1310. if (fdctrl->data_pos != 0)
  1311. if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) {
  1312. FLOPPY_DPRINTF("error seeking to next sector %d\n",
  1313. fd_sector(cur_drv));
  1314. return 0;
  1315. }
  1316. if (bdrv_read(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) {
  1317. FLOPPY_DPRINTF("error getting sector %d\n",
  1318. fd_sector(cur_drv));
  1319. /* Sure, image size is too small... */
  1320. memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
  1321. }
  1322. }
  1323. }
  1324. retval = fdctrl->fifo[pos];
  1325. if (++fdctrl->data_pos == fdctrl->data_len) {
  1326. fdctrl->data_pos = 0;
  1327. /* Switch from transfer mode to status mode
  1328. * then from status mode to command mode
  1329. */
  1330. if (fdctrl->msr & FD_MSR_NONDMA) {
  1331. fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
  1332. } else {
  1333. fdctrl_reset_fifo(fdctrl);
  1334. fdctrl_reset_irq(fdctrl);
  1335. }
  1336. }
  1337. FLOPPY_DPRINTF("data register: 0x%02x\n", retval);
  1338. return retval;
  1339. }
  1340. static void fdctrl_format_sector(FDCtrl *fdctrl)
  1341. {
  1342. FDrive *cur_drv;
  1343. uint8_t kh, kt, ks;
  1344. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1345. cur_drv = get_cur_drv(fdctrl);
  1346. kt = fdctrl->fifo[6];
  1347. kh = fdctrl->fifo[7];
  1348. ks = fdctrl->fifo[8];
  1349. FLOPPY_DPRINTF("format sector at %d %d %02x %02x (%d)\n",
  1350. GET_CUR_DRV(fdctrl), kh, kt, ks,
  1351. fd_sector_calc(kh, kt, ks, cur_drv->last_sect,
  1352. NUM_SIDES(cur_drv)));
  1353. switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & FD_CONFIG_EIS)) {
  1354. case 2:
  1355. /* sect too big */
  1356. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
  1357. fdctrl->fifo[3] = kt;
  1358. fdctrl->fifo[4] = kh;
  1359. fdctrl->fifo[5] = ks;
  1360. return;
  1361. case 3:
  1362. /* track too big */
  1363. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_EC, 0x00);
  1364. fdctrl->fifo[3] = kt;
  1365. fdctrl->fifo[4] = kh;
  1366. fdctrl->fifo[5] = ks;
  1367. return;
  1368. case 4:
  1369. /* No seek enabled */
  1370. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
  1371. fdctrl->fifo[3] = kt;
  1372. fdctrl->fifo[4] = kh;
  1373. fdctrl->fifo[5] = ks;
  1374. return;
  1375. case 1:
  1376. fdctrl->status0 |= FD_SR0_SEEK;
  1377. break;
  1378. default:
  1379. break;
  1380. }
  1381. memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
  1382. if (cur_drv->bs == NULL ||
  1383. bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) {
  1384. FLOPPY_DPRINTF("error formatting sector %d\n", fd_sector(cur_drv));
  1385. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
  1386. } else {
  1387. if (cur_drv->sect == cur_drv->last_sect) {
  1388. fdctrl->data_state &= ~FD_STATE_FORMAT;
  1389. /* Last sector done */
  1390. fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
  1391. } else {
  1392. /* More to do */
  1393. fdctrl->data_pos = 0;
  1394. fdctrl->data_len = 4;
  1395. }
  1396. }
  1397. }
  1398. static void fdctrl_handle_lock(FDCtrl *fdctrl, int direction)
  1399. {
  1400. fdctrl->lock = (fdctrl->fifo[0] & 0x80) ? 1 : 0;
  1401. fdctrl->fifo[0] = fdctrl->lock << 4;
  1402. fdctrl_set_fifo(fdctrl, 1);
  1403. }
  1404. static void fdctrl_handle_dumpreg(FDCtrl *fdctrl, int direction)
  1405. {
  1406. FDrive *cur_drv = get_cur_drv(fdctrl);
  1407. /* Drives position */
  1408. fdctrl->fifo[0] = drv0(fdctrl)->track;
  1409. fdctrl->fifo[1] = drv1(fdctrl)->track;
  1410. #if MAX_FD == 4
  1411. fdctrl->fifo[2] = drv2(fdctrl)->track;
  1412. fdctrl->fifo[3] = drv3(fdctrl)->track;
  1413. #else
  1414. fdctrl->fifo[2] = 0;
  1415. fdctrl->fifo[3] = 0;
  1416. #endif
  1417. /* timers */
  1418. fdctrl->fifo[4] = fdctrl->timer0;
  1419. fdctrl->fifo[5] = (fdctrl->timer1 << 1) | (fdctrl->dor & FD_DOR_DMAEN ? 1 : 0);
  1420. fdctrl->fifo[6] = cur_drv->last_sect;
  1421. fdctrl->fifo[7] = (fdctrl->lock << 7) |
  1422. (cur_drv->perpendicular << 2);
  1423. fdctrl->fifo[8] = fdctrl->config;
  1424. fdctrl->fifo[9] = fdctrl->precomp_trk;
  1425. fdctrl_set_fifo(fdctrl, 10);
  1426. }
  1427. static void fdctrl_handle_version(FDCtrl *fdctrl, int direction)
  1428. {
  1429. /* Controller's version */
  1430. fdctrl->fifo[0] = fdctrl->version;
  1431. fdctrl_set_fifo(fdctrl, 1);
  1432. }
  1433. static void fdctrl_handle_partid(FDCtrl *fdctrl, int direction)
  1434. {
  1435. fdctrl->fifo[0] = 0x41; /* Stepping 1 */
  1436. fdctrl_set_fifo(fdctrl, 1);
  1437. }
  1438. static void fdctrl_handle_restore(FDCtrl *fdctrl, int direction)
  1439. {
  1440. FDrive *cur_drv = get_cur_drv(fdctrl);
  1441. /* Drives position */
  1442. drv0(fdctrl)->track = fdctrl->fifo[3];
  1443. drv1(fdctrl)->track = fdctrl->fifo[4];
  1444. #if MAX_FD == 4
  1445. drv2(fdctrl)->track = fdctrl->fifo[5];
  1446. drv3(fdctrl)->track = fdctrl->fifo[6];
  1447. #endif
  1448. /* timers */
  1449. fdctrl->timer0 = fdctrl->fifo[7];
  1450. fdctrl->timer1 = fdctrl->fifo[8];
  1451. cur_drv->last_sect = fdctrl->fifo[9];
  1452. fdctrl->lock = fdctrl->fifo[10] >> 7;
  1453. cur_drv->perpendicular = (fdctrl->fifo[10] >> 2) & 0xF;
  1454. fdctrl->config = fdctrl->fifo[11];
  1455. fdctrl->precomp_trk = fdctrl->fifo[12];
  1456. fdctrl->pwrd = fdctrl->fifo[13];
  1457. fdctrl_reset_fifo(fdctrl);
  1458. }
  1459. static void fdctrl_handle_save(FDCtrl *fdctrl, int direction)
  1460. {
  1461. FDrive *cur_drv = get_cur_drv(fdctrl);
  1462. fdctrl->fifo[0] = 0;
  1463. fdctrl->fifo[1] = 0;
  1464. /* Drives position */
  1465. fdctrl->fifo[2] = drv0(fdctrl)->track;
  1466. fdctrl->fifo[3] = drv1(fdctrl)->track;
  1467. #if MAX_FD == 4
  1468. fdctrl->fifo[4] = drv2(fdctrl)->track;
  1469. fdctrl->fifo[5] = drv3(fdctrl)->track;
  1470. #else
  1471. fdctrl->fifo[4] = 0;
  1472. fdctrl->fifo[5] = 0;
  1473. #endif
  1474. /* timers */
  1475. fdctrl->fifo[6] = fdctrl->timer0;
  1476. fdctrl->fifo[7] = fdctrl->timer1;
  1477. fdctrl->fifo[8] = cur_drv->last_sect;
  1478. fdctrl->fifo[9] = (fdctrl->lock << 7) |
  1479. (cur_drv->perpendicular << 2);
  1480. fdctrl->fifo[10] = fdctrl->config;
  1481. fdctrl->fifo[11] = fdctrl->precomp_trk;
  1482. fdctrl->fifo[12] = fdctrl->pwrd;
  1483. fdctrl->fifo[13] = 0;
  1484. fdctrl->fifo[14] = 0;
  1485. fdctrl_set_fifo(fdctrl, 15);
  1486. }
  1487. static void fdctrl_handle_readid(FDCtrl *fdctrl, int direction)
  1488. {
  1489. FDrive *cur_drv = get_cur_drv(fdctrl);
  1490. cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
  1491. qemu_mod_timer(fdctrl->result_timer,
  1492. qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() / 50));
  1493. }
  1494. static void fdctrl_handle_format_track(FDCtrl *fdctrl, int direction)
  1495. {
  1496. FDrive *cur_drv;
  1497. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1498. cur_drv = get_cur_drv(fdctrl);
  1499. fdctrl->data_state |= FD_STATE_FORMAT;
  1500. if (fdctrl->fifo[0] & 0x80)
  1501. fdctrl->data_state |= FD_STATE_MULTI;
  1502. else
  1503. fdctrl->data_state &= ~FD_STATE_MULTI;
  1504. cur_drv->bps =
  1505. fdctrl->fifo[2] > 7 ? 16384 : 128 << fdctrl->fifo[2];
  1506. #if 0
  1507. cur_drv->last_sect =
  1508. cur_drv->flags & FDISK_DBL_SIDES ? fdctrl->fifo[3] :
  1509. fdctrl->fifo[3] / 2;
  1510. #else
  1511. cur_drv->last_sect = fdctrl->fifo[3];
  1512. #endif
  1513. /* TODO: implement format using DMA expected by the Bochs BIOS
  1514. * and Linux fdformat (read 3 bytes per sector via DMA and fill
  1515. * the sector with the specified fill byte
  1516. */
  1517. fdctrl->data_state &= ~FD_STATE_FORMAT;
  1518. fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
  1519. }
  1520. static void fdctrl_handle_specify(FDCtrl *fdctrl, int direction)
  1521. {
  1522. fdctrl->timer0 = (fdctrl->fifo[1] >> 4) & 0xF;
  1523. fdctrl->timer1 = fdctrl->fifo[2] >> 1;
  1524. if (fdctrl->fifo[2] & 1)
  1525. fdctrl->dor &= ~FD_DOR_DMAEN;
  1526. else
  1527. fdctrl->dor |= FD_DOR_DMAEN;
  1528. /* No result back */
  1529. fdctrl_reset_fifo(fdctrl);
  1530. }
  1531. static void fdctrl_handle_sense_drive_status(FDCtrl *fdctrl, int direction)
  1532. {
  1533. FDrive *cur_drv;
  1534. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1535. cur_drv = get_cur_drv(fdctrl);
  1536. cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
  1537. /* 1 Byte status back */
  1538. fdctrl->fifo[0] = (cur_drv->ro << 6) |
  1539. (cur_drv->track == 0 ? 0x10 : 0x00) |
  1540. (cur_drv->head << 2) |
  1541. GET_CUR_DRV(fdctrl) |
  1542. 0x28;
  1543. fdctrl_set_fifo(fdctrl, 1);
  1544. }
  1545. static void fdctrl_handle_recalibrate(FDCtrl *fdctrl, int direction)
  1546. {
  1547. FDrive *cur_drv;
  1548. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1549. cur_drv = get_cur_drv(fdctrl);
  1550. fd_recalibrate(cur_drv);
  1551. fdctrl_reset_fifo(fdctrl);
  1552. /* Raise Interrupt */
  1553. fdctrl->status0 |= FD_SR0_SEEK;
  1554. fdctrl_raise_irq(fdctrl);
  1555. }
  1556. static void fdctrl_handle_sense_interrupt_status(FDCtrl *fdctrl, int direction)
  1557. {
  1558. FDrive *cur_drv = get_cur_drv(fdctrl);
  1559. if (fdctrl->reset_sensei > 0) {
  1560. fdctrl->fifo[0] =
  1561. FD_SR0_RDYCHG + FD_RESET_SENSEI_COUNT - fdctrl->reset_sensei;
  1562. fdctrl->reset_sensei--;
  1563. } else if (!(fdctrl->sra & FD_SRA_INTPEND)) {
  1564. fdctrl->fifo[0] = FD_SR0_INVCMD;
  1565. fdctrl_set_fifo(fdctrl, 1);
  1566. return;
  1567. } else {
  1568. fdctrl->fifo[0] =
  1569. (fdctrl->status0 & ~(FD_SR0_HEAD | FD_SR0_DS1 | FD_SR0_DS0))
  1570. | GET_CUR_DRV(fdctrl);
  1571. }
  1572. fdctrl->fifo[1] = cur_drv->track;
  1573. fdctrl_set_fifo(fdctrl, 2);
  1574. fdctrl_reset_irq(fdctrl);
  1575. fdctrl->status0 = FD_SR0_RDYCHG;
  1576. }
  1577. static void fdctrl_handle_seek(FDCtrl *fdctrl, int direction)
  1578. {
  1579. FDrive *cur_drv;
  1580. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1581. cur_drv = get_cur_drv(fdctrl);
  1582. fdctrl_reset_fifo(fdctrl);
  1583. /* The seek command just sends step pulses to the drive and doesn't care if
  1584. * there is a medium inserted of if it's banging the head against the drive.
  1585. */
  1586. fd_seek(cur_drv, cur_drv->head, fdctrl->fifo[2], cur_drv->sect, 1);
  1587. /* Raise Interrupt */
  1588. fdctrl->status0 |= FD_SR0_SEEK;
  1589. fdctrl_raise_irq(fdctrl);
  1590. }
  1591. static void fdctrl_handle_perpendicular_mode(FDCtrl *fdctrl, int direction)
  1592. {
  1593. FDrive *cur_drv = get_cur_drv(fdctrl);
  1594. if (fdctrl->fifo[1] & 0x80)
  1595. cur_drv->perpendicular = fdctrl->fifo[1] & 0x7;
  1596. /* No result back */
  1597. fdctrl_reset_fifo(fdctrl);
  1598. }
  1599. static void fdctrl_handle_configure(FDCtrl *fdctrl, int direction)
  1600. {
  1601. fdctrl->config = fdctrl->fifo[2];
  1602. fdctrl->precomp_trk = fdctrl->fifo[3];
  1603. /* No result back */
  1604. fdctrl_reset_fifo(fdctrl);
  1605. }
  1606. static void fdctrl_handle_powerdown_mode(FDCtrl *fdctrl, int direction)
  1607. {
  1608. fdctrl->pwrd = fdctrl->fifo[1];
  1609. fdctrl->fifo[0] = fdctrl->fifo[1];
  1610. fdctrl_set_fifo(fdctrl, 1);
  1611. }
  1612. static void fdctrl_handle_option(FDCtrl *fdctrl, int direction)
  1613. {
  1614. /* No result back */
  1615. fdctrl_reset_fifo(fdctrl);
  1616. }
  1617. static void fdctrl_handle_drive_specification_command(FDCtrl *fdctrl, int direction)
  1618. {
  1619. FDrive *cur_drv = get_cur_drv(fdctrl);
  1620. if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x80) {
  1621. /* Command parameters done */
  1622. if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x40) {
  1623. fdctrl->fifo[0] = fdctrl->fifo[1];
  1624. fdctrl->fifo[2] = 0;
  1625. fdctrl->fifo[3] = 0;
  1626. fdctrl_set_fifo(fdctrl, 4);
  1627. } else {
  1628. fdctrl_reset_fifo(fdctrl);
  1629. }
  1630. } else if (fdctrl->data_len > 7) {
  1631. /* ERROR */
  1632. fdctrl->fifo[0] = 0x80 |
  1633. (cur_drv->head << 2) | GET_CUR_DRV(fdctrl);
  1634. fdctrl_set_fifo(fdctrl, 1);
  1635. }
  1636. }
  1637. static void fdctrl_handle_relative_seek_in(FDCtrl *fdctrl, int direction)
  1638. {
  1639. FDrive *cur_drv;
  1640. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1641. cur_drv = get_cur_drv(fdctrl);
  1642. if (fdctrl->fifo[2] + cur_drv->track >= cur_drv->max_track) {
  1643. fd_seek(cur_drv, cur_drv->head, cur_drv->max_track - 1,
  1644. cur_drv->sect, 1);
  1645. } else {
  1646. fd_seek(cur_drv, cur_drv->head,
  1647. cur_drv->track + fdctrl->fifo[2], cur_drv->sect, 1);
  1648. }
  1649. fdctrl_reset_fifo(fdctrl);
  1650. /* Raise Interrupt */
  1651. fdctrl->status0 |= FD_SR0_SEEK;
  1652. fdctrl_raise_irq(fdctrl);
  1653. }
  1654. static void fdctrl_handle_relative_seek_out(FDCtrl *fdctrl, int direction)
  1655. {
  1656. FDrive *cur_drv;
  1657. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1658. cur_drv = get_cur_drv(fdctrl);
  1659. if (fdctrl->fifo[2] > cur_drv->track) {
  1660. fd_seek(cur_drv, cur_drv->head, 0, cur_drv->sect, 1);
  1661. } else {
  1662. fd_seek(cur_drv, cur_drv->head,
  1663. cur_drv->track - fdctrl->fifo[2], cur_drv->sect, 1);
  1664. }
  1665. fdctrl_reset_fifo(fdctrl);
  1666. /* Raise Interrupt */
  1667. fdctrl->status0 |= FD_SR0_SEEK;
  1668. fdctrl_raise_irq(fdctrl);
  1669. }
  1670. static const struct {
  1671. uint8_t value;
  1672. uint8_t mask;
  1673. const char* name;
  1674. int parameters;
  1675. void (*handler)(FDCtrl *fdctrl, int direction);
  1676. int direction;
  1677. } handlers[] = {
  1678. { FD_CMD_READ, 0x1f, "READ", 8, fdctrl_start_transfer, FD_DIR_READ },
  1679. { FD_CMD_WRITE, 0x3f, "WRITE", 8, fdctrl_start_transfer, FD_DIR_WRITE },
  1680. { FD_CMD_SEEK, 0xff, "SEEK", 2, fdctrl_handle_seek },
  1681. { FD_CMD_SENSE_INTERRUPT_STATUS, 0xff, "SENSE INTERRUPT STATUS", 0, fdctrl_handle_sense_interrupt_status },
  1682. { FD_CMD_RECALIBRATE, 0xff, "RECALIBRATE", 1, fdctrl_handle_recalibrate },
  1683. { FD_CMD_FORMAT_TRACK, 0xbf, "FORMAT TRACK", 5, fdctrl_handle_format_track },
  1684. { FD_CMD_READ_TRACK, 0xbf, "READ TRACK", 8, fdctrl_start_transfer, FD_DIR_READ },
  1685. { FD_CMD_RESTORE, 0xff, "RESTORE", 17, fdctrl_handle_restore }, /* part of READ DELETED DATA */
  1686. { FD_CMD_SAVE, 0xff, "SAVE", 0, fdctrl_handle_save }, /* part of READ DELETED DATA */
  1687. { FD_CMD_READ_DELETED, 0x1f, "READ DELETED DATA", 8, fdctrl_start_transfer_del, FD_DIR_READ },
  1688. { FD_CMD_SCAN_EQUAL, 0x1f, "SCAN EQUAL", 8, fdctrl_start_transfer, FD_DIR_SCANE },
  1689. { FD_CMD_VERIFY, 0x1f, "VERIFY", 8, fdctrl_start_transfer, FD_DIR_VERIFY },
  1690. { FD_CMD_SCAN_LOW_OR_EQUAL, 0x1f, "SCAN LOW OR EQUAL", 8, fdctrl_start_transfer, FD_DIR_SCANL },
  1691. { FD_CMD_SCAN_HIGH_OR_EQUAL, 0x1f, "SCAN HIGH OR EQUAL", 8, fdctrl_start_transfer, FD_DIR_SCANH },
  1692. { FD_CMD_WRITE_DELETED, 0x3f, "WRITE DELETED DATA", 8, fdctrl_start_transfer_del, FD_DIR_WRITE },
  1693. { FD_CMD_READ_ID, 0xbf, "READ ID", 1, fdctrl_handle_readid },
  1694. { FD_CMD_SPECIFY, 0xff, "SPECIFY", 2, fdctrl_handle_specify },
  1695. { FD_CMD_SENSE_DRIVE_STATUS, 0xff, "SENSE DRIVE STATUS", 1, fdctrl_handle_sense_drive_status },
  1696. { FD_CMD_PERPENDICULAR_MODE, 0xff, "PERPENDICULAR MODE", 1, fdctrl_handle_perpendicular_mode },
  1697. { FD_CMD_CONFIGURE, 0xff, "CONFIGURE", 3, fdctrl_handle_configure },
  1698. { FD_CMD_POWERDOWN_MODE, 0xff, "POWERDOWN MODE", 2, fdctrl_handle_powerdown_mode },
  1699. { FD_CMD_OPTION, 0xff, "OPTION", 1, fdctrl_handle_option },
  1700. { FD_CMD_DRIVE_SPECIFICATION_COMMAND, 0xff, "DRIVE SPECIFICATION COMMAND", 5, fdctrl_handle_drive_specification_command },
  1701. { FD_CMD_RELATIVE_SEEK_OUT, 0xff, "RELATIVE SEEK OUT", 2, fdctrl_handle_relative_seek_out },
  1702. { FD_CMD_FORMAT_AND_WRITE, 0xff, "FORMAT AND WRITE", 10, fdctrl_unimplemented },
  1703. { FD_CMD_RELATIVE_SEEK_IN, 0xff, "RELATIVE SEEK IN", 2, fdctrl_handle_relative_seek_in },
  1704. { FD_CMD_LOCK, 0x7f, "LOCK", 0, fdctrl_handle_lock },
  1705. { FD_CMD_DUMPREG, 0xff, "DUMPREG", 0, fdctrl_handle_dumpreg },
  1706. { FD_CMD_VERSION, 0xff, "VERSION", 0, fdctrl_handle_version },
  1707. { FD_CMD_PART_ID, 0xff, "PART ID", 0, fdctrl_handle_partid },
  1708. { FD_CMD_WRITE, 0x1f, "WRITE (BeOS)", 8, fdctrl_start_transfer, FD_DIR_WRITE }, /* not in specification ; BeOS 4.5 bug */
  1709. { 0, 0, "unknown", 0, fdctrl_unimplemented }, /* default handler */
  1710. };
  1711. /* Associate command to an index in the 'handlers' array */
  1712. static uint8_t command_to_handler[256];
  1713. static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value)
  1714. {
  1715. FDrive *cur_drv;
  1716. int pos;
  1717. /* Reset mode */
  1718. if (!(fdctrl->dor & FD_DOR_nRESET)) {
  1719. FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
  1720. return;
  1721. }
  1722. if (!(fdctrl->msr & FD_MSR_RQM) || (fdctrl->msr & FD_MSR_DIO)) {
  1723. FLOPPY_DPRINTF("error: controller not ready for writing\n");
  1724. return;
  1725. }
  1726. fdctrl->dsr &= ~FD_DSR_PWRDOWN;
  1727. /* Is it write command time ? */
  1728. if (fdctrl->msr & FD_MSR_NONDMA) {
  1729. /* FIFO data write */
  1730. pos = fdctrl->data_pos++;
  1731. pos %= FD_SECTOR_LEN;
  1732. fdctrl->fifo[pos] = value;
  1733. if (pos == FD_SECTOR_LEN - 1 ||
  1734. fdctrl->data_pos == fdctrl->data_len) {
  1735. cur_drv = get_cur_drv(fdctrl);
  1736. if (bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) {
  1737. FLOPPY_DPRINTF("error writing sector %d\n",
  1738. fd_sector(cur_drv));
  1739. return;
  1740. }
  1741. if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) {
  1742. FLOPPY_DPRINTF("error seeking to next sector %d\n",
  1743. fd_sector(cur_drv));
  1744. return;
  1745. }
  1746. }
  1747. /* Switch from transfer mode to status mode
  1748. * then from status mode to command mode
  1749. */
  1750. if (fdctrl->data_pos == fdctrl->data_len)
  1751. fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
  1752. return;
  1753. }
  1754. if (fdctrl->data_pos == 0) {
  1755. /* Command */
  1756. pos = command_to_handler[value & 0xff];
  1757. FLOPPY_DPRINTF("%s command\n", handlers[pos].name);
  1758. fdctrl->data_len = handlers[pos].parameters + 1;
  1759. fdctrl->msr |= FD_MSR_CMDBUSY;
  1760. }
  1761. FLOPPY_DPRINTF("%s: %02x\n", __func__, value);
  1762. fdctrl->fifo[fdctrl->data_pos++] = value;
  1763. if (fdctrl->data_pos == fdctrl->data_len) {
  1764. /* We now have all parameters
  1765. * and will be able to treat the command
  1766. */
  1767. if (fdctrl->data_state & FD_STATE_FORMAT) {
  1768. fdctrl_format_sector(fdctrl);
  1769. return;
  1770. }
  1771. pos = command_to_handler[fdctrl->fifo[0] & 0xff];
  1772. FLOPPY_DPRINTF("treat %s command\n", handlers[pos].name);
  1773. (*handlers[pos].handler)(fdctrl, handlers[pos].direction);
  1774. }
  1775. }
  1776. static void fdctrl_result_timer(void *opaque)
  1777. {
  1778. FDCtrl *fdctrl = opaque;
  1779. FDrive *cur_drv = get_cur_drv(fdctrl);
  1780. /* Pretend we are spinning.
  1781. * This is needed for Coherent, which uses READ ID to check for
  1782. * sector interleaving.
  1783. */
  1784. if (cur_drv->last_sect != 0) {
  1785. cur_drv->sect = (cur_drv->sect % cur_drv->last_sect) + 1;
  1786. }
  1787. /* READ_ID can't automatically succeed! */
  1788. if (fdctrl->check_media_rate &&
  1789. (fdctrl->dsr & FD_DSR_DRATEMASK) != cur_drv->media_rate) {
  1790. FLOPPY_DPRINTF("read id rate mismatch (fdc=%d, media=%d)\n",
  1791. fdctrl->dsr & FD_DSR_DRATEMASK, cur_drv->media_rate);
  1792. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA, 0x00);
  1793. } else {
  1794. fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
  1795. }
  1796. }
  1797. static void fdctrl_change_cb(void *opaque, bool load)
  1798. {
  1799. FDrive *drive = opaque;
  1800. drive->media_changed = 1;
  1801. fd_revalidate(drive);
  1802. }
  1803. static const BlockDevOps fdctrl_block_ops = {
  1804. .change_media_cb = fdctrl_change_cb,
  1805. };
  1806. /* Init functions */
  1807. static int fdctrl_connect_drives(FDCtrl *fdctrl)
  1808. {
  1809. unsigned int i;
  1810. FDrive *drive;
  1811. for (i = 0; i < MAX_FD; i++) {
  1812. drive = &fdctrl->drives[i];
  1813. drive->fdctrl = fdctrl;
  1814. if (drive->bs) {
  1815. if (bdrv_get_on_error(drive->bs, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
  1816. error_report("fdc doesn't support drive option werror");
  1817. return -1;
  1818. }
  1819. if (bdrv_get_on_error(drive->bs, 1) != BLOCKDEV_ON_ERROR_REPORT) {
  1820. error_report("fdc doesn't support drive option rerror");
  1821. return -1;
  1822. }
  1823. }
  1824. fd_init(drive);
  1825. fdctrl_change_cb(drive, 0);
  1826. if (drive->bs) {
  1827. bdrv_set_dev_ops(drive->bs, &fdctrl_block_ops, drive);
  1828. }
  1829. }
  1830. return 0;
  1831. }
  1832. ISADevice *fdctrl_init_isa(ISABus *bus, DriveInfo **fds)
  1833. {
  1834. ISADevice *dev;
  1835. dev = isa_try_create(bus, "isa-fdc");
  1836. if (!dev) {
  1837. return NULL;
  1838. }
  1839. if (fds[0]) {
  1840. qdev_prop_set_drive_nofail(&dev->qdev, "driveA", fds[0]->bdrv);
  1841. }
  1842. if (fds[1]) {
  1843. qdev_prop_set_drive_nofail(&dev->qdev, "driveB", fds[1]->bdrv);
  1844. }
  1845. qdev_init_nofail(&dev->qdev);
  1846. return dev;
  1847. }
  1848. void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
  1849. hwaddr mmio_base, DriveInfo **fds)
  1850. {
  1851. FDCtrl *fdctrl;
  1852. DeviceState *dev;
  1853. FDCtrlSysBus *sys;
  1854. dev = qdev_create(NULL, "sysbus-fdc");
  1855. sys = DO_UPCAST(FDCtrlSysBus, busdev.qdev, dev);
  1856. fdctrl = &sys->state;
  1857. fdctrl->dma_chann = dma_chann; /* FIXME */
  1858. if (fds[0]) {
  1859. qdev_prop_set_drive_nofail(dev, "driveA", fds[0]->bdrv);
  1860. }
  1861. if (fds[1]) {
  1862. qdev_prop_set_drive_nofail(dev, "driveB", fds[1]->bdrv);
  1863. }
  1864. qdev_init_nofail(dev);
  1865. sysbus_connect_irq(&sys->busdev, 0, irq);
  1866. sysbus_mmio_map(&sys->busdev, 0, mmio_base);
  1867. }
  1868. void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base,
  1869. DriveInfo **fds, qemu_irq *fdc_tc)
  1870. {
  1871. DeviceState *dev;
  1872. FDCtrlSysBus *sys;
  1873. dev = qdev_create(NULL, "SUNW,fdtwo");
  1874. if (fds[0]) {
  1875. qdev_prop_set_drive_nofail(dev, "drive", fds[0]->bdrv);
  1876. }
  1877. qdev_init_nofail(dev);
  1878. sys = DO_UPCAST(FDCtrlSysBus, busdev.qdev, dev);
  1879. sysbus_connect_irq(&sys->busdev, 0, irq);
  1880. sysbus_mmio_map(&sys->busdev, 0, io_base);
  1881. *fdc_tc = qdev_get_gpio_in(dev, 0);
  1882. }
  1883. static int fdctrl_init_common(FDCtrl *fdctrl)
  1884. {
  1885. int i, j;
  1886. static int command_tables_inited = 0;
  1887. /* Fill 'command_to_handler' lookup table */
  1888. if (!command_tables_inited) {
  1889. command_tables_inited = 1;
  1890. for (i = ARRAY_SIZE(handlers) - 1; i >= 0; i--) {
  1891. for (j = 0; j < sizeof(command_to_handler); j++) {
  1892. if ((j & handlers[i].mask) == handlers[i].value) {
  1893. command_to_handler[j] = i;
  1894. }
  1895. }
  1896. }
  1897. }
  1898. FLOPPY_DPRINTF("init controller\n");
  1899. fdctrl->fifo = qemu_memalign(512, FD_SECTOR_LEN);
  1900. fdctrl->fifo_size = 512;
  1901. fdctrl->result_timer = qemu_new_timer_ns(vm_clock,
  1902. fdctrl_result_timer, fdctrl);
  1903. fdctrl->version = 0x90; /* Intel 82078 controller */
  1904. fdctrl->config = FD_CONFIG_EIS | FD_CONFIG_EFIFO; /* Implicit seek, polling & FIFO enabled */
  1905. fdctrl->num_floppies = MAX_FD;
  1906. if (fdctrl->dma_chann != -1)
  1907. DMA_register_channel(fdctrl->dma_chann, &fdctrl_transfer_handler, fdctrl);
  1908. return fdctrl_connect_drives(fdctrl);
  1909. }
  1910. static const MemoryRegionPortio fdc_portio_list[] = {
  1911. { 1, 5, 1, .read = fdctrl_read, .write = fdctrl_write },
  1912. { 7, 1, 1, .read = fdctrl_read, .write = fdctrl_write },
  1913. PORTIO_END_OF_LIST(),
  1914. };
  1915. static int isabus_fdc_init1(ISADevice *dev)
  1916. {
  1917. FDCtrlISABus *isa = DO_UPCAST(FDCtrlISABus, busdev, dev);
  1918. FDCtrl *fdctrl = &isa->state;
  1919. int ret;
  1920. isa_register_portio_list(dev, isa->iobase, fdc_portio_list, fdctrl, "fdc");
  1921. isa_init_irq(&isa->busdev, &fdctrl->irq, isa->irq);
  1922. fdctrl->dma_chann = isa->dma;
  1923. qdev_set_legacy_instance_id(&dev->qdev, isa->iobase, 2);
  1924. ret = fdctrl_init_common(fdctrl);
  1925. add_boot_device_path(isa->bootindexA, &dev->qdev, "/floppy@0");
  1926. add_boot_device_path(isa->bootindexB, &dev->qdev, "/floppy@1");
  1927. return ret;
  1928. }
  1929. static int sysbus_fdc_init1(SysBusDevice *dev)
  1930. {
  1931. FDCtrlSysBus *sys = DO_UPCAST(FDCtrlSysBus, busdev, dev);
  1932. FDCtrl *fdctrl = &sys->state;
  1933. int ret;
  1934. memory_region_init_io(&fdctrl->iomem, &fdctrl_mem_ops, fdctrl, "fdc", 0x08);
  1935. sysbus_init_mmio(dev, &fdctrl->iomem);
  1936. sysbus_init_irq(dev, &fdctrl->irq);
  1937. qdev_init_gpio_in(&dev->qdev, fdctrl_handle_tc, 1);
  1938. fdctrl->dma_chann = -1;
  1939. qdev_set_legacy_instance_id(&dev->qdev, 0 /* io */, 2); /* FIXME */
  1940. ret = fdctrl_init_common(fdctrl);
  1941. return ret;
  1942. }
  1943. static int sun4m_fdc_init1(SysBusDevice *dev)
  1944. {
  1945. FDCtrl *fdctrl = &(FROM_SYSBUS(FDCtrlSysBus, dev)->state);
  1946. memory_region_init_io(&fdctrl->iomem, &fdctrl_mem_strict_ops, fdctrl,
  1947. "fdctrl", 0x08);
  1948. sysbus_init_mmio(dev, &fdctrl->iomem);
  1949. sysbus_init_irq(dev, &fdctrl->irq);
  1950. qdev_init_gpio_in(&dev->qdev, fdctrl_handle_tc, 1);
  1951. fdctrl->sun4m = 1;
  1952. qdev_set_legacy_instance_id(&dev->qdev, 0 /* io */, 2); /* FIXME */
  1953. return fdctrl_init_common(fdctrl);
  1954. }
  1955. FDriveType isa_fdc_get_drive_type(ISADevice *fdc, int i)
  1956. {
  1957. FDCtrlISABus *isa = DO_UPCAST(FDCtrlISABus, busdev, fdc);
  1958. return isa->state.drives[i].drive;
  1959. }
  1960. static const VMStateDescription vmstate_isa_fdc ={
  1961. .name = "fdc",
  1962. .version_id = 2,
  1963. .minimum_version_id = 2,
  1964. .fields = (VMStateField []) {
  1965. VMSTATE_STRUCT(state, FDCtrlISABus, 0, vmstate_fdc, FDCtrl),
  1966. VMSTATE_END_OF_LIST()
  1967. }
  1968. };
  1969. static Property isa_fdc_properties[] = {
  1970. DEFINE_PROP_HEX32("iobase", FDCtrlISABus, iobase, 0x3f0),
  1971. DEFINE_PROP_UINT32("irq", FDCtrlISABus, irq, 6),
  1972. DEFINE_PROP_UINT32("dma", FDCtrlISABus, dma, 2),
  1973. DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.drives[0].bs),
  1974. DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.drives[1].bs),
  1975. DEFINE_PROP_INT32("bootindexA", FDCtrlISABus, bootindexA, -1),
  1976. DEFINE_PROP_INT32("bootindexB", FDCtrlISABus, bootindexB, -1),
  1977. DEFINE_PROP_BIT("check_media_rate", FDCtrlISABus, state.check_media_rate,
  1978. 0, true),
  1979. DEFINE_PROP_END_OF_LIST(),
  1980. };
  1981. static void isabus_fdc_class_init1(ObjectClass *klass, void *data)
  1982. {
  1983. DeviceClass *dc = DEVICE_CLASS(klass);
  1984. ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
  1985. ic->init = isabus_fdc_init1;
  1986. dc->fw_name = "fdc";
  1987. dc->no_user = 1;
  1988. dc->reset = fdctrl_external_reset_isa;
  1989. dc->vmsd = &vmstate_isa_fdc;
  1990. dc->props = isa_fdc_properties;
  1991. }
  1992. static const TypeInfo isa_fdc_info = {
  1993. .name = "isa-fdc",
  1994. .parent = TYPE_ISA_DEVICE,
  1995. .instance_size = sizeof(FDCtrlISABus),
  1996. .class_init = isabus_fdc_class_init1,
  1997. };
  1998. static const VMStateDescription vmstate_sysbus_fdc ={
  1999. .name = "fdc",
  2000. .version_id = 2,
  2001. .minimum_version_id = 2,
  2002. .fields = (VMStateField []) {
  2003. VMSTATE_STRUCT(state, FDCtrlSysBus, 0, vmstate_fdc, FDCtrl),
  2004. VMSTATE_END_OF_LIST()
  2005. }
  2006. };
  2007. static Property sysbus_fdc_properties[] = {
  2008. DEFINE_PROP_DRIVE("driveA", FDCtrlSysBus, state.drives[0].bs),
  2009. DEFINE_PROP_DRIVE("driveB", FDCtrlSysBus, state.drives[1].bs),
  2010. DEFINE_PROP_END_OF_LIST(),
  2011. };
  2012. static void sysbus_fdc_class_init(ObjectClass *klass, void *data)
  2013. {
  2014. DeviceClass *dc = DEVICE_CLASS(klass);
  2015. SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
  2016. k->init = sysbus_fdc_init1;
  2017. dc->reset = fdctrl_external_reset_sysbus;
  2018. dc->vmsd = &vmstate_sysbus_fdc;
  2019. dc->props = sysbus_fdc_properties;
  2020. }
  2021. static const TypeInfo sysbus_fdc_info = {
  2022. .name = "sysbus-fdc",
  2023. .parent = TYPE_SYS_BUS_DEVICE,
  2024. .instance_size = sizeof(FDCtrlSysBus),
  2025. .class_init = sysbus_fdc_class_init,
  2026. };
  2027. static Property sun4m_fdc_properties[] = {
  2028. DEFINE_PROP_DRIVE("drive", FDCtrlSysBus, state.drives[0].bs),
  2029. DEFINE_PROP_END_OF_LIST(),
  2030. };
  2031. static void sun4m_fdc_class_init(ObjectClass *klass, void *data)
  2032. {
  2033. DeviceClass *dc = DEVICE_CLASS(klass);
  2034. SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
  2035. k->init = sun4m_fdc_init1;
  2036. dc->reset = fdctrl_external_reset_sysbus;
  2037. dc->vmsd = &vmstate_sysbus_fdc;
  2038. dc->props = sun4m_fdc_properties;
  2039. }
  2040. static const TypeInfo sun4m_fdc_info = {
  2041. .name = "SUNW,fdtwo",
  2042. .parent = TYPE_SYS_BUS_DEVICE,
  2043. .instance_size = sizeof(FDCtrlSysBus),
  2044. .class_init = sun4m_fdc_class_init,
  2045. };
  2046. static void fdc_register_types(void)
  2047. {
  2048. type_register_static(&isa_fdc_info);
  2049. type_register_static(&sysbus_fdc_info);
  2050. type_register_static(&sun4m_fdc_info);
  2051. }
  2052. type_init(fdc_register_types)