fdc.c 69 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279
  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.h"
  32. #include "qemu-timer.h"
  33. #include "isa.h"
  34. #include "sysbus.h"
  35. #include "qdev-addr.h"
  36. #include "blockdev.h"
  37. #include "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, uint8_t status0);
  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. };
  324. enum {
  325. FD_STATE_MULTI = 0x01, /* multi track flag */
  326. FD_STATE_FORMAT = 0x02, /* format flag */
  327. FD_STATE_SEEK = 0x04, /* seek 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_DID_SEEK(state) ((state) & FD_STATE_SEEK)
  456. #define FD_FORMAT_CMD(state) ((state) & FD_STATE_FORMAT)
  457. struct FDCtrl {
  458. MemoryRegion iomem;
  459. qemu_irq irq;
  460. /* Controller state */
  461. QEMUTimer *result_timer;
  462. int dma_chann;
  463. /* Controller's identification */
  464. uint8_t version;
  465. /* HW */
  466. uint8_t sra;
  467. uint8_t srb;
  468. uint8_t dor;
  469. uint8_t dor_vmstate; /* only used as temp during vmstate */
  470. uint8_t tdr;
  471. uint8_t dsr;
  472. uint8_t msr;
  473. uint8_t cur_drv;
  474. uint8_t status0;
  475. uint8_t status1;
  476. uint8_t status2;
  477. /* Command FIFO */
  478. uint8_t *fifo;
  479. int32_t fifo_size;
  480. uint32_t data_pos;
  481. uint32_t data_len;
  482. uint8_t data_state;
  483. uint8_t data_dir;
  484. uint8_t eot; /* last wanted sector */
  485. /* States kept only to be returned back */
  486. /* precompensation */
  487. uint8_t precomp_trk;
  488. uint8_t config;
  489. uint8_t lock;
  490. /* Power down config (also with status regB access mode */
  491. uint8_t pwrd;
  492. /* Floppy drives */
  493. uint8_t num_floppies;
  494. /* Sun4m quirks? */
  495. int sun4m;
  496. FDrive drives[MAX_FD];
  497. int reset_sensei;
  498. uint32_t check_media_rate;
  499. /* Timers state */
  500. uint8_t timer0;
  501. uint8_t timer1;
  502. };
  503. typedef struct FDCtrlSysBus {
  504. SysBusDevice busdev;
  505. struct FDCtrl state;
  506. } FDCtrlSysBus;
  507. typedef struct FDCtrlISABus {
  508. ISADevice busdev;
  509. uint32_t iobase;
  510. uint32_t irq;
  511. uint32_t dma;
  512. struct FDCtrl state;
  513. int32_t bootindexA;
  514. int32_t bootindexB;
  515. } FDCtrlISABus;
  516. static uint32_t fdctrl_read (void *opaque, uint32_t reg)
  517. {
  518. FDCtrl *fdctrl = opaque;
  519. uint32_t retval;
  520. reg &= 7;
  521. switch (reg) {
  522. case FD_REG_SRA:
  523. retval = fdctrl_read_statusA(fdctrl);
  524. break;
  525. case FD_REG_SRB:
  526. retval = fdctrl_read_statusB(fdctrl);
  527. break;
  528. case FD_REG_DOR:
  529. retval = fdctrl_read_dor(fdctrl);
  530. break;
  531. case FD_REG_TDR:
  532. retval = fdctrl_read_tape(fdctrl);
  533. break;
  534. case FD_REG_MSR:
  535. retval = fdctrl_read_main_status(fdctrl);
  536. break;
  537. case FD_REG_FIFO:
  538. retval = fdctrl_read_data(fdctrl);
  539. break;
  540. case FD_REG_DIR:
  541. retval = fdctrl_read_dir(fdctrl);
  542. break;
  543. default:
  544. retval = (uint32_t)(-1);
  545. break;
  546. }
  547. FLOPPY_DPRINTF("read reg%d: 0x%02x\n", reg & 7, retval);
  548. return retval;
  549. }
  550. static void fdctrl_write (void *opaque, uint32_t reg, uint32_t value)
  551. {
  552. FDCtrl *fdctrl = opaque;
  553. FLOPPY_DPRINTF("write reg%d: 0x%02x\n", reg & 7, value);
  554. reg &= 7;
  555. switch (reg) {
  556. case FD_REG_DOR:
  557. fdctrl_write_dor(fdctrl, value);
  558. break;
  559. case FD_REG_TDR:
  560. fdctrl_write_tape(fdctrl, value);
  561. break;
  562. case FD_REG_DSR:
  563. fdctrl_write_rate(fdctrl, value);
  564. break;
  565. case FD_REG_FIFO:
  566. fdctrl_write_data(fdctrl, value);
  567. break;
  568. case FD_REG_CCR:
  569. fdctrl_write_ccr(fdctrl, value);
  570. break;
  571. default:
  572. break;
  573. }
  574. }
  575. static uint64_t fdctrl_read_mem (void *opaque, target_phys_addr_t reg,
  576. unsigned ize)
  577. {
  578. return fdctrl_read(opaque, (uint32_t)reg);
  579. }
  580. static void fdctrl_write_mem (void *opaque, target_phys_addr_t reg,
  581. uint64_t value, unsigned size)
  582. {
  583. fdctrl_write(opaque, (uint32_t)reg, value);
  584. }
  585. static const MemoryRegionOps fdctrl_mem_ops = {
  586. .read = fdctrl_read_mem,
  587. .write = fdctrl_write_mem,
  588. .endianness = DEVICE_NATIVE_ENDIAN,
  589. };
  590. static const MemoryRegionOps fdctrl_mem_strict_ops = {
  591. .read = fdctrl_read_mem,
  592. .write = fdctrl_write_mem,
  593. .endianness = DEVICE_NATIVE_ENDIAN,
  594. .valid = {
  595. .min_access_size = 1,
  596. .max_access_size = 1,
  597. },
  598. };
  599. static bool fdrive_media_changed_needed(void *opaque)
  600. {
  601. FDrive *drive = opaque;
  602. return (drive->bs != NULL && drive->media_changed != 1);
  603. }
  604. static const VMStateDescription vmstate_fdrive_media_changed = {
  605. .name = "fdrive/media_changed",
  606. .version_id = 1,
  607. .minimum_version_id = 1,
  608. .minimum_version_id_old = 1,
  609. .fields = (VMStateField[]) {
  610. VMSTATE_UINT8(media_changed, FDrive),
  611. VMSTATE_END_OF_LIST()
  612. }
  613. };
  614. static bool fdrive_media_rate_needed(void *opaque)
  615. {
  616. FDrive *drive = opaque;
  617. return drive->fdctrl->check_media_rate;
  618. }
  619. static const VMStateDescription vmstate_fdrive_media_rate = {
  620. .name = "fdrive/media_rate",
  621. .version_id = 1,
  622. .minimum_version_id = 1,
  623. .minimum_version_id_old = 1,
  624. .fields = (VMStateField[]) {
  625. VMSTATE_UINT8(media_rate, FDrive),
  626. VMSTATE_END_OF_LIST()
  627. }
  628. };
  629. static const VMStateDescription vmstate_fdrive = {
  630. .name = "fdrive",
  631. .version_id = 1,
  632. .minimum_version_id = 1,
  633. .minimum_version_id_old = 1,
  634. .fields = (VMStateField[]) {
  635. VMSTATE_UINT8(head, FDrive),
  636. VMSTATE_UINT8(track, FDrive),
  637. VMSTATE_UINT8(sect, FDrive),
  638. VMSTATE_END_OF_LIST()
  639. },
  640. .subsections = (VMStateSubsection[]) {
  641. {
  642. .vmsd = &vmstate_fdrive_media_changed,
  643. .needed = &fdrive_media_changed_needed,
  644. } , {
  645. .vmsd = &vmstate_fdrive_media_rate,
  646. .needed = &fdrive_media_rate_needed,
  647. } , {
  648. /* empty */
  649. }
  650. }
  651. };
  652. static void fdc_pre_save(void *opaque)
  653. {
  654. FDCtrl *s = opaque;
  655. s->dor_vmstate = s->dor | GET_CUR_DRV(s);
  656. }
  657. static int fdc_post_load(void *opaque, int version_id)
  658. {
  659. FDCtrl *s = opaque;
  660. SET_CUR_DRV(s, s->dor_vmstate & FD_DOR_SELMASK);
  661. s->dor = s->dor_vmstate & ~FD_DOR_SELMASK;
  662. return 0;
  663. }
  664. static const VMStateDescription vmstate_fdc = {
  665. .name = "fdc",
  666. .version_id = 2,
  667. .minimum_version_id = 2,
  668. .minimum_version_id_old = 2,
  669. .pre_save = fdc_pre_save,
  670. .post_load = fdc_post_load,
  671. .fields = (VMStateField []) {
  672. /* Controller State */
  673. VMSTATE_UINT8(sra, FDCtrl),
  674. VMSTATE_UINT8(srb, FDCtrl),
  675. VMSTATE_UINT8(dor_vmstate, FDCtrl),
  676. VMSTATE_UINT8(tdr, FDCtrl),
  677. VMSTATE_UINT8(dsr, FDCtrl),
  678. VMSTATE_UINT8(msr, FDCtrl),
  679. VMSTATE_UINT8(status0, FDCtrl),
  680. VMSTATE_UINT8(status1, FDCtrl),
  681. VMSTATE_UINT8(status2, FDCtrl),
  682. /* Command FIFO */
  683. VMSTATE_VARRAY_INT32(fifo, FDCtrl, fifo_size, 0, vmstate_info_uint8,
  684. uint8_t),
  685. VMSTATE_UINT32(data_pos, FDCtrl),
  686. VMSTATE_UINT32(data_len, FDCtrl),
  687. VMSTATE_UINT8(data_state, FDCtrl),
  688. VMSTATE_UINT8(data_dir, FDCtrl),
  689. VMSTATE_UINT8(eot, FDCtrl),
  690. /* States kept only to be returned back */
  691. VMSTATE_UINT8(timer0, FDCtrl),
  692. VMSTATE_UINT8(timer1, FDCtrl),
  693. VMSTATE_UINT8(precomp_trk, FDCtrl),
  694. VMSTATE_UINT8(config, FDCtrl),
  695. VMSTATE_UINT8(lock, FDCtrl),
  696. VMSTATE_UINT8(pwrd, FDCtrl),
  697. VMSTATE_UINT8_EQUAL(num_floppies, FDCtrl),
  698. VMSTATE_STRUCT_ARRAY(drives, FDCtrl, MAX_FD, 1,
  699. vmstate_fdrive, FDrive),
  700. VMSTATE_END_OF_LIST()
  701. }
  702. };
  703. static void fdctrl_external_reset_sysbus(DeviceState *d)
  704. {
  705. FDCtrlSysBus *sys = container_of(d, FDCtrlSysBus, busdev.qdev);
  706. FDCtrl *s = &sys->state;
  707. fdctrl_reset(s, 0);
  708. }
  709. static void fdctrl_external_reset_isa(DeviceState *d)
  710. {
  711. FDCtrlISABus *isa = container_of(d, FDCtrlISABus, busdev.qdev);
  712. FDCtrl *s = &isa->state;
  713. fdctrl_reset(s, 0);
  714. }
  715. static void fdctrl_handle_tc(void *opaque, int irq, int level)
  716. {
  717. //FDCtrl *s = opaque;
  718. if (level) {
  719. // XXX
  720. FLOPPY_DPRINTF("TC pulsed\n");
  721. }
  722. }
  723. /* Change IRQ state */
  724. static void fdctrl_reset_irq(FDCtrl *fdctrl)
  725. {
  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, uint8_t status0)
  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. fdctrl->status0 = status0;
  740. return;
  741. }
  742. if (!(fdctrl->sra & FD_SRA_INTPEND)) {
  743. qemu_set_irq(fdctrl->irq, 1);
  744. fdctrl->sra |= FD_SRA_INTPEND;
  745. }
  746. fdctrl->reset_sensei = 0;
  747. fdctrl->status0 = status0;
  748. FLOPPY_DPRINTF("Set interrupt status to 0x%02x\n", fdctrl->status0);
  749. }
  750. /* Reset controller */
  751. static void fdctrl_reset(FDCtrl *fdctrl, int do_irq)
  752. {
  753. int i;
  754. FLOPPY_DPRINTF("reset controller\n");
  755. fdctrl_reset_irq(fdctrl);
  756. /* Initialise controller */
  757. fdctrl->sra = 0;
  758. fdctrl->srb = 0xc0;
  759. if (!fdctrl->drives[1].bs)
  760. fdctrl->sra |= FD_SRA_nDRV2;
  761. fdctrl->cur_drv = 0;
  762. fdctrl->dor = FD_DOR_nRESET;
  763. fdctrl->dor |= (fdctrl->dma_chann != -1) ? FD_DOR_DMAEN : 0;
  764. fdctrl->msr = FD_MSR_RQM;
  765. /* FIFO state */
  766. fdctrl->data_pos = 0;
  767. fdctrl->data_len = 0;
  768. fdctrl->data_state = 0;
  769. fdctrl->data_dir = FD_DIR_WRITE;
  770. for (i = 0; i < MAX_FD; i++)
  771. fd_recalibrate(&fdctrl->drives[i]);
  772. fdctrl_reset_fifo(fdctrl);
  773. if (do_irq) {
  774. fdctrl_raise_irq(fdctrl, FD_SR0_RDYCHG);
  775. fdctrl->reset_sensei = FD_RESET_SENSEI_COUNT;
  776. }
  777. }
  778. static inline FDrive *drv0(FDCtrl *fdctrl)
  779. {
  780. return &fdctrl->drives[(fdctrl->tdr & FD_TDR_BOOTSEL) >> 2];
  781. }
  782. static inline FDrive *drv1(FDCtrl *fdctrl)
  783. {
  784. if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (1 << 2))
  785. return &fdctrl->drives[1];
  786. else
  787. return &fdctrl->drives[0];
  788. }
  789. #if MAX_FD == 4
  790. static inline FDrive *drv2(FDCtrl *fdctrl)
  791. {
  792. if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (2 << 2))
  793. return &fdctrl->drives[2];
  794. else
  795. return &fdctrl->drives[1];
  796. }
  797. static inline FDrive *drv3(FDCtrl *fdctrl)
  798. {
  799. if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (3 << 2))
  800. return &fdctrl->drives[3];
  801. else
  802. return &fdctrl->drives[2];
  803. }
  804. #endif
  805. static FDrive *get_cur_drv(FDCtrl *fdctrl)
  806. {
  807. switch (fdctrl->cur_drv) {
  808. case 0: return drv0(fdctrl);
  809. case 1: return drv1(fdctrl);
  810. #if MAX_FD == 4
  811. case 2: return drv2(fdctrl);
  812. case 3: return drv3(fdctrl);
  813. #endif
  814. default: return NULL;
  815. }
  816. }
  817. /* Status A register : 0x00 (read-only) */
  818. static uint32_t fdctrl_read_statusA(FDCtrl *fdctrl)
  819. {
  820. uint32_t retval = fdctrl->sra;
  821. FLOPPY_DPRINTF("status register A: 0x%02x\n", retval);
  822. return retval;
  823. }
  824. /* Status B register : 0x01 (read-only) */
  825. static uint32_t fdctrl_read_statusB(FDCtrl *fdctrl)
  826. {
  827. uint32_t retval = fdctrl->srb;
  828. FLOPPY_DPRINTF("status register B: 0x%02x\n", retval);
  829. return retval;
  830. }
  831. /* Digital output register : 0x02 */
  832. static uint32_t fdctrl_read_dor(FDCtrl *fdctrl)
  833. {
  834. uint32_t retval = fdctrl->dor;
  835. /* Selected drive */
  836. retval |= fdctrl->cur_drv;
  837. FLOPPY_DPRINTF("digital output register: 0x%02x\n", retval);
  838. return retval;
  839. }
  840. static void fdctrl_write_dor(FDCtrl *fdctrl, uint32_t value)
  841. {
  842. FLOPPY_DPRINTF("digital output register set to 0x%02x\n", value);
  843. /* Motors */
  844. if (value & FD_DOR_MOTEN0)
  845. fdctrl->srb |= FD_SRB_MTR0;
  846. else
  847. fdctrl->srb &= ~FD_SRB_MTR0;
  848. if (value & FD_DOR_MOTEN1)
  849. fdctrl->srb |= FD_SRB_MTR1;
  850. else
  851. fdctrl->srb &= ~FD_SRB_MTR1;
  852. /* Drive */
  853. if (value & 1)
  854. fdctrl->srb |= FD_SRB_DR0;
  855. else
  856. fdctrl->srb &= ~FD_SRB_DR0;
  857. /* Reset */
  858. if (!(value & FD_DOR_nRESET)) {
  859. if (fdctrl->dor & FD_DOR_nRESET) {
  860. FLOPPY_DPRINTF("controller enter RESET state\n");
  861. }
  862. } else {
  863. if (!(fdctrl->dor & FD_DOR_nRESET)) {
  864. FLOPPY_DPRINTF("controller out of RESET state\n");
  865. fdctrl_reset(fdctrl, 1);
  866. fdctrl->dsr &= ~FD_DSR_PWRDOWN;
  867. }
  868. }
  869. /* Selected drive */
  870. fdctrl->cur_drv = value & FD_DOR_SELMASK;
  871. fdctrl->dor = value;
  872. }
  873. /* Tape drive register : 0x03 */
  874. static uint32_t fdctrl_read_tape(FDCtrl *fdctrl)
  875. {
  876. uint32_t retval = fdctrl->tdr;
  877. FLOPPY_DPRINTF("tape drive register: 0x%02x\n", retval);
  878. return retval;
  879. }
  880. static void fdctrl_write_tape(FDCtrl *fdctrl, uint32_t value)
  881. {
  882. /* Reset mode */
  883. if (!(fdctrl->dor & FD_DOR_nRESET)) {
  884. FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
  885. return;
  886. }
  887. FLOPPY_DPRINTF("tape drive register set to 0x%02x\n", value);
  888. /* Disk boot selection indicator */
  889. fdctrl->tdr = value & FD_TDR_BOOTSEL;
  890. /* Tape indicators: never allow */
  891. }
  892. /* Main status register : 0x04 (read) */
  893. static uint32_t fdctrl_read_main_status(FDCtrl *fdctrl)
  894. {
  895. uint32_t retval = fdctrl->msr;
  896. fdctrl->dsr &= ~FD_DSR_PWRDOWN;
  897. fdctrl->dor |= FD_DOR_nRESET;
  898. /* Sparc mutation */
  899. if (fdctrl->sun4m) {
  900. retval |= FD_MSR_DIO;
  901. fdctrl_reset_irq(fdctrl);
  902. };
  903. FLOPPY_DPRINTF("main status register: 0x%02x\n", retval);
  904. return retval;
  905. }
  906. /* Data select rate register : 0x04 (write) */
  907. static void fdctrl_write_rate(FDCtrl *fdctrl, uint32_t value)
  908. {
  909. /* Reset mode */
  910. if (!(fdctrl->dor & FD_DOR_nRESET)) {
  911. FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
  912. return;
  913. }
  914. FLOPPY_DPRINTF("select rate register set to 0x%02x\n", value);
  915. /* Reset: autoclear */
  916. if (value & FD_DSR_SWRESET) {
  917. fdctrl->dor &= ~FD_DOR_nRESET;
  918. fdctrl_reset(fdctrl, 1);
  919. fdctrl->dor |= FD_DOR_nRESET;
  920. }
  921. if (value & FD_DSR_PWRDOWN) {
  922. fdctrl_reset(fdctrl, 1);
  923. }
  924. fdctrl->dsr = value;
  925. }
  926. /* Configuration control register: 0x07 (write) */
  927. static void fdctrl_write_ccr(FDCtrl *fdctrl, uint32_t value)
  928. {
  929. /* Reset mode */
  930. if (!(fdctrl->dor & FD_DOR_nRESET)) {
  931. FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
  932. return;
  933. }
  934. FLOPPY_DPRINTF("configuration control register set to 0x%02x\n", value);
  935. /* Only the rate selection bits used in AT mode, and we
  936. * store those in the DSR.
  937. */
  938. fdctrl->dsr = (fdctrl->dsr & ~FD_DSR_DRATEMASK) |
  939. (value & FD_DSR_DRATEMASK);
  940. }
  941. static int fdctrl_media_changed(FDrive *drv)
  942. {
  943. return drv->media_changed;
  944. }
  945. /* Digital input register : 0x07 (read-only) */
  946. static uint32_t fdctrl_read_dir(FDCtrl *fdctrl)
  947. {
  948. uint32_t retval = 0;
  949. if (fdctrl_media_changed(get_cur_drv(fdctrl))) {
  950. retval |= FD_DIR_DSKCHG;
  951. }
  952. if (retval != 0) {
  953. FLOPPY_DPRINTF("Floppy digital input register: 0x%02x\n", retval);
  954. }
  955. return retval;
  956. }
  957. /* FIFO state control */
  958. static void fdctrl_reset_fifo(FDCtrl *fdctrl)
  959. {
  960. fdctrl->data_dir = FD_DIR_WRITE;
  961. fdctrl->data_pos = 0;
  962. fdctrl->msr &= ~(FD_MSR_CMDBUSY | FD_MSR_DIO);
  963. }
  964. /* Set FIFO status for the host to read */
  965. static void fdctrl_set_fifo(FDCtrl *fdctrl, int fifo_len, uint8_t status0)
  966. {
  967. fdctrl->data_dir = FD_DIR_READ;
  968. fdctrl->data_len = fifo_len;
  969. fdctrl->data_pos = 0;
  970. fdctrl->msr |= FD_MSR_CMDBUSY | FD_MSR_RQM | FD_MSR_DIO;
  971. if (status0) {
  972. fdctrl_raise_irq(fdctrl, status0);
  973. }
  974. }
  975. /* Set an error: unimplemented/unknown command */
  976. static void fdctrl_unimplemented(FDCtrl *fdctrl, int direction)
  977. {
  978. qemu_log_mask(LOG_UNIMP, "fdc: unimplemented command 0x%02x\n",
  979. fdctrl->fifo[0]);
  980. fdctrl->fifo[0] = FD_SR0_INVCMD;
  981. fdctrl_set_fifo(fdctrl, 1, 0);
  982. }
  983. /* Seek to next sector
  984. * returns 0 when end of track reached (for DBL_SIDES on head 1)
  985. * otherwise returns 1
  986. */
  987. static int fdctrl_seek_to_next_sect(FDCtrl *fdctrl, FDrive *cur_drv)
  988. {
  989. FLOPPY_DPRINTF("seek to next sector (%d %02x %02x => %d)\n",
  990. cur_drv->head, cur_drv->track, cur_drv->sect,
  991. fd_sector(cur_drv));
  992. /* XXX: cur_drv->sect >= cur_drv->last_sect should be an
  993. error in fact */
  994. uint8_t new_head = cur_drv->head;
  995. uint8_t new_track = cur_drv->track;
  996. uint8_t new_sect = cur_drv->sect;
  997. int ret = 1;
  998. if (new_sect >= cur_drv->last_sect ||
  999. new_sect == fdctrl->eot) {
  1000. new_sect = 1;
  1001. if (FD_MULTI_TRACK(fdctrl->data_state)) {
  1002. if (new_head == 0 &&
  1003. (cur_drv->flags & FDISK_DBL_SIDES) != 0) {
  1004. new_head = 1;
  1005. } else {
  1006. new_head = 0;
  1007. new_track++;
  1008. if ((cur_drv->flags & FDISK_DBL_SIDES) == 0) {
  1009. ret = 0;
  1010. }
  1011. }
  1012. } else {
  1013. new_track++;
  1014. ret = 0;
  1015. }
  1016. if (ret == 1) {
  1017. FLOPPY_DPRINTF("seek to next track (%d %02x %02x => %d)\n",
  1018. new_head, new_track, new_sect, fd_sector(cur_drv));
  1019. }
  1020. } else {
  1021. new_sect++;
  1022. }
  1023. fd_seek(cur_drv, new_head, new_track, new_sect, 1);
  1024. return ret;
  1025. }
  1026. /* Callback for transfer end (stop or abort) */
  1027. static void fdctrl_stop_transfer(FDCtrl *fdctrl, uint8_t status0,
  1028. uint8_t status1, uint8_t status2)
  1029. {
  1030. FDrive *cur_drv;
  1031. cur_drv = get_cur_drv(fdctrl);
  1032. fdctrl->status0 = status0 | FD_SR0_SEEK | (cur_drv->head << 2) |
  1033. GET_CUR_DRV(fdctrl);
  1034. FLOPPY_DPRINTF("transfer status: %02x %02x %02x (%02x)\n",
  1035. status0, status1, status2, fdctrl->status0);
  1036. fdctrl->fifo[0] = fdctrl->status0;
  1037. fdctrl->fifo[1] = status1;
  1038. fdctrl->fifo[2] = status2;
  1039. fdctrl->fifo[3] = cur_drv->track;
  1040. fdctrl->fifo[4] = cur_drv->head;
  1041. fdctrl->fifo[5] = cur_drv->sect;
  1042. fdctrl->fifo[6] = FD_SECTOR_SC;
  1043. fdctrl->data_dir = FD_DIR_READ;
  1044. if (!(fdctrl->msr & FD_MSR_NONDMA)) {
  1045. DMA_release_DREQ(fdctrl->dma_chann);
  1046. }
  1047. fdctrl->msr |= FD_MSR_RQM | FD_MSR_DIO;
  1048. fdctrl->msr &= ~FD_MSR_NONDMA;
  1049. fdctrl_set_fifo(fdctrl, 7, fdctrl->status0);
  1050. }
  1051. /* Prepare a data transfer (either DMA or FIFO) */
  1052. static void fdctrl_start_transfer(FDCtrl *fdctrl, int direction)
  1053. {
  1054. FDrive *cur_drv;
  1055. uint8_t kh, kt, ks;
  1056. int did_seek = 0;
  1057. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1058. cur_drv = get_cur_drv(fdctrl);
  1059. kt = fdctrl->fifo[2];
  1060. kh = fdctrl->fifo[3];
  1061. ks = fdctrl->fifo[4];
  1062. FLOPPY_DPRINTF("Start transfer at %d %d %02x %02x (%d)\n",
  1063. GET_CUR_DRV(fdctrl), kh, kt, ks,
  1064. fd_sector_calc(kh, kt, ks, cur_drv->last_sect,
  1065. NUM_SIDES(cur_drv)));
  1066. switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & FD_CONFIG_EIS)) {
  1067. case 2:
  1068. /* sect too big */
  1069. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
  1070. fdctrl->fifo[3] = kt;
  1071. fdctrl->fifo[4] = kh;
  1072. fdctrl->fifo[5] = ks;
  1073. return;
  1074. case 3:
  1075. /* track too big */
  1076. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_EC, 0x00);
  1077. fdctrl->fifo[3] = kt;
  1078. fdctrl->fifo[4] = kh;
  1079. fdctrl->fifo[5] = ks;
  1080. return;
  1081. case 4:
  1082. /* No seek enabled */
  1083. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
  1084. fdctrl->fifo[3] = kt;
  1085. fdctrl->fifo[4] = kh;
  1086. fdctrl->fifo[5] = ks;
  1087. return;
  1088. case 1:
  1089. did_seek = 1;
  1090. break;
  1091. default:
  1092. break;
  1093. }
  1094. /* Check the data rate. If the programmed data rate does not match
  1095. * the currently inserted medium, the operation has to fail. */
  1096. if (fdctrl->check_media_rate &&
  1097. (fdctrl->dsr & FD_DSR_DRATEMASK) != cur_drv->media_rate) {
  1098. FLOPPY_DPRINTF("data rate mismatch (fdc=%d, media=%d)\n",
  1099. fdctrl->dsr & FD_DSR_DRATEMASK, cur_drv->media_rate);
  1100. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA, 0x00);
  1101. fdctrl->fifo[3] = kt;
  1102. fdctrl->fifo[4] = kh;
  1103. fdctrl->fifo[5] = ks;
  1104. return;
  1105. }
  1106. /* Set the FIFO state */
  1107. fdctrl->data_dir = direction;
  1108. fdctrl->data_pos = 0;
  1109. fdctrl->msr |= FD_MSR_CMDBUSY;
  1110. if (fdctrl->fifo[0] & 0x80)
  1111. fdctrl->data_state |= FD_STATE_MULTI;
  1112. else
  1113. fdctrl->data_state &= ~FD_STATE_MULTI;
  1114. if (did_seek)
  1115. fdctrl->data_state |= FD_STATE_SEEK;
  1116. else
  1117. fdctrl->data_state &= ~FD_STATE_SEEK;
  1118. if (fdctrl->fifo[5] == 00) {
  1119. fdctrl->data_len = fdctrl->fifo[8];
  1120. } else {
  1121. int tmp;
  1122. fdctrl->data_len = 128 << (fdctrl->fifo[5] > 7 ? 7 : fdctrl->fifo[5]);
  1123. tmp = (fdctrl->fifo[6] - ks + 1);
  1124. if (fdctrl->fifo[0] & 0x80)
  1125. tmp += fdctrl->fifo[6];
  1126. fdctrl->data_len *= tmp;
  1127. }
  1128. fdctrl->eot = fdctrl->fifo[6];
  1129. if (fdctrl->dor & FD_DOR_DMAEN) {
  1130. int dma_mode;
  1131. /* DMA transfer are enabled. Check if DMA channel is well programmed */
  1132. dma_mode = DMA_get_channel_mode(fdctrl->dma_chann);
  1133. dma_mode = (dma_mode >> 2) & 3;
  1134. FLOPPY_DPRINTF("dma_mode=%d direction=%d (%d - %d)\n",
  1135. dma_mode, direction,
  1136. (128 << fdctrl->fifo[5]) *
  1137. (cur_drv->last_sect - ks + 1), fdctrl->data_len);
  1138. if (((direction == FD_DIR_SCANE || direction == FD_DIR_SCANL ||
  1139. direction == FD_DIR_SCANH) && dma_mode == 0) ||
  1140. (direction == FD_DIR_WRITE && dma_mode == 2) ||
  1141. (direction == FD_DIR_READ && dma_mode == 1)) {
  1142. /* No access is allowed until DMA transfer has completed */
  1143. fdctrl->msr &= ~FD_MSR_RQM;
  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. return;
  1150. } else {
  1151. FLOPPY_DPRINTF("bad dma_mode=%d direction=%d\n", dma_mode,
  1152. direction);
  1153. }
  1154. }
  1155. FLOPPY_DPRINTF("start non-DMA transfer\n");
  1156. fdctrl->msr |= FD_MSR_NONDMA;
  1157. if (direction != FD_DIR_WRITE)
  1158. fdctrl->msr |= FD_MSR_DIO;
  1159. /* IO based transfer: calculate len */
  1160. fdctrl_raise_irq(fdctrl, FD_SR0_SEEK);
  1161. return;
  1162. }
  1163. /* Prepare a transfer of deleted data */
  1164. static void fdctrl_start_transfer_del(FDCtrl *fdctrl, int direction)
  1165. {
  1166. qemu_log_mask(LOG_UNIMP, "fdctrl_start_transfer_del() unimplemented\n");
  1167. /* We don't handle deleted data,
  1168. * so we don't return *ANYTHING*
  1169. */
  1170. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
  1171. }
  1172. /* handlers for DMA transfers */
  1173. static int fdctrl_transfer_handler (void *opaque, int nchan,
  1174. int dma_pos, int dma_len)
  1175. {
  1176. FDCtrl *fdctrl;
  1177. FDrive *cur_drv;
  1178. int len, start_pos, rel_pos;
  1179. uint8_t status0 = 0x00, status1 = 0x00, status2 = 0x00;
  1180. fdctrl = opaque;
  1181. if (fdctrl->msr & FD_MSR_RQM) {
  1182. FLOPPY_DPRINTF("Not in DMA transfer mode !\n");
  1183. return 0;
  1184. }
  1185. cur_drv = get_cur_drv(fdctrl);
  1186. if (fdctrl->data_dir == FD_DIR_SCANE || fdctrl->data_dir == FD_DIR_SCANL ||
  1187. fdctrl->data_dir == FD_DIR_SCANH)
  1188. status2 = FD_SR2_SNS;
  1189. if (dma_len > fdctrl->data_len)
  1190. dma_len = fdctrl->data_len;
  1191. if (cur_drv->bs == NULL) {
  1192. if (fdctrl->data_dir == FD_DIR_WRITE)
  1193. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
  1194. else
  1195. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
  1196. len = 0;
  1197. goto transfer_error;
  1198. }
  1199. rel_pos = fdctrl->data_pos % FD_SECTOR_LEN;
  1200. for (start_pos = fdctrl->data_pos; fdctrl->data_pos < dma_len;) {
  1201. len = dma_len - fdctrl->data_pos;
  1202. if (len + rel_pos > FD_SECTOR_LEN)
  1203. len = FD_SECTOR_LEN - rel_pos;
  1204. FLOPPY_DPRINTF("copy %d bytes (%d %d %d) %d pos %d %02x "
  1205. "(%d-0x%08x 0x%08x)\n", len, dma_len, fdctrl->data_pos,
  1206. fdctrl->data_len, GET_CUR_DRV(fdctrl), cur_drv->head,
  1207. cur_drv->track, cur_drv->sect, fd_sector(cur_drv),
  1208. fd_sector(cur_drv) * FD_SECTOR_LEN);
  1209. if (fdctrl->data_dir != FD_DIR_WRITE ||
  1210. len < FD_SECTOR_LEN || rel_pos != 0) {
  1211. /* READ & SCAN commands and realign to a sector for WRITE */
  1212. if (bdrv_read(cur_drv->bs, fd_sector(cur_drv),
  1213. fdctrl->fifo, 1) < 0) {
  1214. FLOPPY_DPRINTF("Floppy: error getting sector %d\n",
  1215. fd_sector(cur_drv));
  1216. /* Sure, image size is too small... */
  1217. memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
  1218. }
  1219. }
  1220. switch (fdctrl->data_dir) {
  1221. case FD_DIR_READ:
  1222. /* READ commands */
  1223. DMA_write_memory (nchan, fdctrl->fifo + rel_pos,
  1224. fdctrl->data_pos, len);
  1225. break;
  1226. case FD_DIR_WRITE:
  1227. /* WRITE commands */
  1228. if (cur_drv->ro) {
  1229. /* Handle readonly medium early, no need to do DMA, touch the
  1230. * LED or attempt any writes. A real floppy doesn't attempt
  1231. * to write to readonly media either. */
  1232. fdctrl_stop_transfer(fdctrl,
  1233. FD_SR0_ABNTERM | FD_SR0_SEEK, FD_SR1_NW,
  1234. 0x00);
  1235. goto transfer_error;
  1236. }
  1237. DMA_read_memory (nchan, fdctrl->fifo + rel_pos,
  1238. fdctrl->data_pos, len);
  1239. if (bdrv_write(cur_drv->bs, fd_sector(cur_drv),
  1240. fdctrl->fifo, 1) < 0) {
  1241. FLOPPY_DPRINTF("error writing sector %d\n",
  1242. fd_sector(cur_drv));
  1243. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
  1244. goto transfer_error;
  1245. }
  1246. break;
  1247. default:
  1248. /* SCAN commands */
  1249. {
  1250. uint8_t tmpbuf[FD_SECTOR_LEN];
  1251. int ret;
  1252. DMA_read_memory (nchan, tmpbuf, fdctrl->data_pos, len);
  1253. ret = memcmp(tmpbuf, fdctrl->fifo + rel_pos, len);
  1254. if (ret == 0) {
  1255. status2 = FD_SR2_SEH;
  1256. goto end_transfer;
  1257. }
  1258. if ((ret < 0 && fdctrl->data_dir == FD_DIR_SCANL) ||
  1259. (ret > 0 && fdctrl->data_dir == FD_DIR_SCANH)) {
  1260. status2 = 0x00;
  1261. goto end_transfer;
  1262. }
  1263. }
  1264. break;
  1265. }
  1266. fdctrl->data_pos += len;
  1267. rel_pos = fdctrl->data_pos % FD_SECTOR_LEN;
  1268. if (rel_pos == 0) {
  1269. /* Seek to next sector */
  1270. if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv))
  1271. break;
  1272. }
  1273. }
  1274. end_transfer:
  1275. len = fdctrl->data_pos - start_pos;
  1276. FLOPPY_DPRINTF("end transfer %d %d %d\n",
  1277. fdctrl->data_pos, len, fdctrl->data_len);
  1278. if (fdctrl->data_dir == FD_DIR_SCANE ||
  1279. fdctrl->data_dir == FD_DIR_SCANL ||
  1280. fdctrl->data_dir == FD_DIR_SCANH)
  1281. status2 = FD_SR2_SEH;
  1282. if (FD_DID_SEEK(fdctrl->data_state))
  1283. status0 |= FD_SR0_SEEK;
  1284. fdctrl->data_len -= len;
  1285. fdctrl_stop_transfer(fdctrl, status0, status1, status2);
  1286. transfer_error:
  1287. return len;
  1288. }
  1289. /* Data register : 0x05 */
  1290. static uint32_t fdctrl_read_data(FDCtrl *fdctrl)
  1291. {
  1292. FDrive *cur_drv;
  1293. uint32_t retval = 0;
  1294. int pos;
  1295. cur_drv = get_cur_drv(fdctrl);
  1296. fdctrl->dsr &= ~FD_DSR_PWRDOWN;
  1297. if (!(fdctrl->msr & FD_MSR_RQM) || !(fdctrl->msr & FD_MSR_DIO)) {
  1298. FLOPPY_DPRINTF("error: controller not ready for reading\n");
  1299. return 0;
  1300. }
  1301. pos = fdctrl->data_pos;
  1302. if (fdctrl->msr & FD_MSR_NONDMA) {
  1303. pos %= FD_SECTOR_LEN;
  1304. if (pos == 0) {
  1305. if (fdctrl->data_pos != 0)
  1306. if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) {
  1307. FLOPPY_DPRINTF("error seeking to next sector %d\n",
  1308. fd_sector(cur_drv));
  1309. return 0;
  1310. }
  1311. if (bdrv_read(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) {
  1312. FLOPPY_DPRINTF("error getting sector %d\n",
  1313. fd_sector(cur_drv));
  1314. /* Sure, image size is too small... */
  1315. memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
  1316. }
  1317. }
  1318. }
  1319. retval = fdctrl->fifo[pos];
  1320. if (++fdctrl->data_pos == fdctrl->data_len) {
  1321. fdctrl->data_pos = 0;
  1322. /* Switch from transfer mode to status mode
  1323. * then from status mode to command mode
  1324. */
  1325. if (fdctrl->msr & FD_MSR_NONDMA) {
  1326. fdctrl_stop_transfer(fdctrl, FD_SR0_SEEK, 0x00, 0x00);
  1327. } else {
  1328. fdctrl_reset_fifo(fdctrl);
  1329. fdctrl_reset_irq(fdctrl);
  1330. }
  1331. }
  1332. FLOPPY_DPRINTF("data register: 0x%02x\n", retval);
  1333. return retval;
  1334. }
  1335. static void fdctrl_format_sector(FDCtrl *fdctrl)
  1336. {
  1337. FDrive *cur_drv;
  1338. uint8_t kh, kt, ks;
  1339. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1340. cur_drv = get_cur_drv(fdctrl);
  1341. kt = fdctrl->fifo[6];
  1342. kh = fdctrl->fifo[7];
  1343. ks = fdctrl->fifo[8];
  1344. FLOPPY_DPRINTF("format sector at %d %d %02x %02x (%d)\n",
  1345. GET_CUR_DRV(fdctrl), kh, kt, ks,
  1346. fd_sector_calc(kh, kt, ks, cur_drv->last_sect,
  1347. NUM_SIDES(cur_drv)));
  1348. switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & FD_CONFIG_EIS)) {
  1349. case 2:
  1350. /* sect too big */
  1351. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
  1352. fdctrl->fifo[3] = kt;
  1353. fdctrl->fifo[4] = kh;
  1354. fdctrl->fifo[5] = ks;
  1355. return;
  1356. case 3:
  1357. /* track too big */
  1358. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_EC, 0x00);
  1359. fdctrl->fifo[3] = kt;
  1360. fdctrl->fifo[4] = kh;
  1361. fdctrl->fifo[5] = ks;
  1362. return;
  1363. case 4:
  1364. /* No seek enabled */
  1365. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
  1366. fdctrl->fifo[3] = kt;
  1367. fdctrl->fifo[4] = kh;
  1368. fdctrl->fifo[5] = ks;
  1369. return;
  1370. case 1:
  1371. fdctrl->data_state |= FD_STATE_SEEK;
  1372. break;
  1373. default:
  1374. break;
  1375. }
  1376. memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
  1377. if (cur_drv->bs == NULL ||
  1378. bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) {
  1379. FLOPPY_DPRINTF("error formatting sector %d\n", fd_sector(cur_drv));
  1380. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
  1381. } else {
  1382. if (cur_drv->sect == cur_drv->last_sect) {
  1383. fdctrl->data_state &= ~FD_STATE_FORMAT;
  1384. /* Last sector done */
  1385. if (FD_DID_SEEK(fdctrl->data_state))
  1386. fdctrl_stop_transfer(fdctrl, FD_SR0_SEEK, 0x00, 0x00);
  1387. else
  1388. fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
  1389. } else {
  1390. /* More to do */
  1391. fdctrl->data_pos = 0;
  1392. fdctrl->data_len = 4;
  1393. }
  1394. }
  1395. }
  1396. static void fdctrl_handle_lock(FDCtrl *fdctrl, int direction)
  1397. {
  1398. fdctrl->lock = (fdctrl->fifo[0] & 0x80) ? 1 : 0;
  1399. fdctrl->fifo[0] = fdctrl->lock << 4;
  1400. fdctrl_set_fifo(fdctrl, 1, 0);
  1401. }
  1402. static void fdctrl_handle_dumpreg(FDCtrl *fdctrl, int direction)
  1403. {
  1404. FDrive *cur_drv = get_cur_drv(fdctrl);
  1405. /* Drives position */
  1406. fdctrl->fifo[0] = drv0(fdctrl)->track;
  1407. fdctrl->fifo[1] = drv1(fdctrl)->track;
  1408. #if MAX_FD == 4
  1409. fdctrl->fifo[2] = drv2(fdctrl)->track;
  1410. fdctrl->fifo[3] = drv3(fdctrl)->track;
  1411. #else
  1412. fdctrl->fifo[2] = 0;
  1413. fdctrl->fifo[3] = 0;
  1414. #endif
  1415. /* timers */
  1416. fdctrl->fifo[4] = fdctrl->timer0;
  1417. fdctrl->fifo[5] = (fdctrl->timer1 << 1) | (fdctrl->dor & FD_DOR_DMAEN ? 1 : 0);
  1418. fdctrl->fifo[6] = cur_drv->last_sect;
  1419. fdctrl->fifo[7] = (fdctrl->lock << 7) |
  1420. (cur_drv->perpendicular << 2);
  1421. fdctrl->fifo[8] = fdctrl->config;
  1422. fdctrl->fifo[9] = fdctrl->precomp_trk;
  1423. fdctrl_set_fifo(fdctrl, 10, 0);
  1424. }
  1425. static void fdctrl_handle_version(FDCtrl *fdctrl, int direction)
  1426. {
  1427. /* Controller's version */
  1428. fdctrl->fifo[0] = fdctrl->version;
  1429. fdctrl_set_fifo(fdctrl, 1, 0);
  1430. }
  1431. static void fdctrl_handle_partid(FDCtrl *fdctrl, int direction)
  1432. {
  1433. fdctrl->fifo[0] = 0x41; /* Stepping 1 */
  1434. fdctrl_set_fifo(fdctrl, 1, 0);
  1435. }
  1436. static void fdctrl_handle_restore(FDCtrl *fdctrl, int direction)
  1437. {
  1438. FDrive *cur_drv = get_cur_drv(fdctrl);
  1439. /* Drives position */
  1440. drv0(fdctrl)->track = fdctrl->fifo[3];
  1441. drv1(fdctrl)->track = fdctrl->fifo[4];
  1442. #if MAX_FD == 4
  1443. drv2(fdctrl)->track = fdctrl->fifo[5];
  1444. drv3(fdctrl)->track = fdctrl->fifo[6];
  1445. #endif
  1446. /* timers */
  1447. fdctrl->timer0 = fdctrl->fifo[7];
  1448. fdctrl->timer1 = fdctrl->fifo[8];
  1449. cur_drv->last_sect = fdctrl->fifo[9];
  1450. fdctrl->lock = fdctrl->fifo[10] >> 7;
  1451. cur_drv->perpendicular = (fdctrl->fifo[10] >> 2) & 0xF;
  1452. fdctrl->config = fdctrl->fifo[11];
  1453. fdctrl->precomp_trk = fdctrl->fifo[12];
  1454. fdctrl->pwrd = fdctrl->fifo[13];
  1455. fdctrl_reset_fifo(fdctrl);
  1456. }
  1457. static void fdctrl_handle_save(FDCtrl *fdctrl, int direction)
  1458. {
  1459. FDrive *cur_drv = get_cur_drv(fdctrl);
  1460. fdctrl->fifo[0] = 0;
  1461. fdctrl->fifo[1] = 0;
  1462. /* Drives position */
  1463. fdctrl->fifo[2] = drv0(fdctrl)->track;
  1464. fdctrl->fifo[3] = drv1(fdctrl)->track;
  1465. #if MAX_FD == 4
  1466. fdctrl->fifo[4] = drv2(fdctrl)->track;
  1467. fdctrl->fifo[5] = drv3(fdctrl)->track;
  1468. #else
  1469. fdctrl->fifo[4] = 0;
  1470. fdctrl->fifo[5] = 0;
  1471. #endif
  1472. /* timers */
  1473. fdctrl->fifo[6] = fdctrl->timer0;
  1474. fdctrl->fifo[7] = fdctrl->timer1;
  1475. fdctrl->fifo[8] = cur_drv->last_sect;
  1476. fdctrl->fifo[9] = (fdctrl->lock << 7) |
  1477. (cur_drv->perpendicular << 2);
  1478. fdctrl->fifo[10] = fdctrl->config;
  1479. fdctrl->fifo[11] = fdctrl->precomp_trk;
  1480. fdctrl->fifo[12] = fdctrl->pwrd;
  1481. fdctrl->fifo[13] = 0;
  1482. fdctrl->fifo[14] = 0;
  1483. fdctrl_set_fifo(fdctrl, 15, 0);
  1484. }
  1485. static void fdctrl_handle_readid(FDCtrl *fdctrl, int direction)
  1486. {
  1487. FDrive *cur_drv = get_cur_drv(fdctrl);
  1488. cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
  1489. qemu_mod_timer(fdctrl->result_timer,
  1490. qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() / 50));
  1491. }
  1492. static void fdctrl_handle_format_track(FDCtrl *fdctrl, int direction)
  1493. {
  1494. FDrive *cur_drv;
  1495. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1496. cur_drv = get_cur_drv(fdctrl);
  1497. fdctrl->data_state |= FD_STATE_FORMAT;
  1498. if (fdctrl->fifo[0] & 0x80)
  1499. fdctrl->data_state |= FD_STATE_MULTI;
  1500. else
  1501. fdctrl->data_state &= ~FD_STATE_MULTI;
  1502. fdctrl->data_state &= ~FD_STATE_SEEK;
  1503. cur_drv->bps =
  1504. fdctrl->fifo[2] > 7 ? 16384 : 128 << fdctrl->fifo[2];
  1505. #if 0
  1506. cur_drv->last_sect =
  1507. cur_drv->flags & FDISK_DBL_SIDES ? fdctrl->fifo[3] :
  1508. fdctrl->fifo[3] / 2;
  1509. #else
  1510. cur_drv->last_sect = fdctrl->fifo[3];
  1511. #endif
  1512. /* TODO: implement format using DMA expected by the Bochs BIOS
  1513. * and Linux fdformat (read 3 bytes per sector via DMA and fill
  1514. * the sector with the specified fill byte
  1515. */
  1516. fdctrl->data_state &= ~FD_STATE_FORMAT;
  1517. fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
  1518. }
  1519. static void fdctrl_handle_specify(FDCtrl *fdctrl, int direction)
  1520. {
  1521. fdctrl->timer0 = (fdctrl->fifo[1] >> 4) & 0xF;
  1522. fdctrl->timer1 = fdctrl->fifo[2] >> 1;
  1523. if (fdctrl->fifo[2] & 1)
  1524. fdctrl->dor &= ~FD_DOR_DMAEN;
  1525. else
  1526. fdctrl->dor |= FD_DOR_DMAEN;
  1527. /* No result back */
  1528. fdctrl_reset_fifo(fdctrl);
  1529. }
  1530. static void fdctrl_handle_sense_drive_status(FDCtrl *fdctrl, int direction)
  1531. {
  1532. FDrive *cur_drv;
  1533. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1534. cur_drv = get_cur_drv(fdctrl);
  1535. cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
  1536. /* 1 Byte status back */
  1537. fdctrl->fifo[0] = (cur_drv->ro << 6) |
  1538. (cur_drv->track == 0 ? 0x10 : 0x00) |
  1539. (cur_drv->head << 2) |
  1540. GET_CUR_DRV(fdctrl) |
  1541. 0x28;
  1542. fdctrl_set_fifo(fdctrl, 1, 0);
  1543. }
  1544. static void fdctrl_handle_recalibrate(FDCtrl *fdctrl, int direction)
  1545. {
  1546. FDrive *cur_drv;
  1547. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1548. cur_drv = get_cur_drv(fdctrl);
  1549. fd_recalibrate(cur_drv);
  1550. fdctrl_reset_fifo(fdctrl);
  1551. /* Raise Interrupt */
  1552. fdctrl_raise_irq(fdctrl, FD_SR0_SEEK);
  1553. }
  1554. static void fdctrl_handle_sense_interrupt_status(FDCtrl *fdctrl, int direction)
  1555. {
  1556. FDrive *cur_drv = get_cur_drv(fdctrl);
  1557. if (fdctrl->reset_sensei > 0) {
  1558. fdctrl->fifo[0] =
  1559. FD_SR0_RDYCHG + FD_RESET_SENSEI_COUNT - fdctrl->reset_sensei;
  1560. fdctrl->reset_sensei--;
  1561. } else if (!(fdctrl->sra & FD_SRA_INTPEND)) {
  1562. fdctrl->fifo[0] = FD_SR0_INVCMD;
  1563. fdctrl_set_fifo(fdctrl, 1, 0);
  1564. return;
  1565. } else {
  1566. fdctrl->fifo[0] =
  1567. (fdctrl->status0 & ~(FD_SR0_HEAD | FD_SR0_DS1 | FD_SR0_DS0))
  1568. | GET_CUR_DRV(fdctrl);
  1569. }
  1570. fdctrl->fifo[1] = cur_drv->track;
  1571. fdctrl_set_fifo(fdctrl, 2, 0);
  1572. fdctrl_reset_irq(fdctrl);
  1573. fdctrl->status0 = FD_SR0_RDYCHG;
  1574. }
  1575. static void fdctrl_handle_seek(FDCtrl *fdctrl, int direction)
  1576. {
  1577. FDrive *cur_drv;
  1578. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1579. cur_drv = get_cur_drv(fdctrl);
  1580. fdctrl_reset_fifo(fdctrl);
  1581. /* The seek command just sends step pulses to the drive and doesn't care if
  1582. * there is a medium inserted of if it's banging the head against the drive.
  1583. */
  1584. fd_seek(cur_drv, cur_drv->head, fdctrl->fifo[2], cur_drv->sect, 1);
  1585. /* Raise Interrupt */
  1586. fdctrl_raise_irq(fdctrl, FD_SR0_SEEK);
  1587. }
  1588. static void fdctrl_handle_perpendicular_mode(FDCtrl *fdctrl, int direction)
  1589. {
  1590. FDrive *cur_drv = get_cur_drv(fdctrl);
  1591. if (fdctrl->fifo[1] & 0x80)
  1592. cur_drv->perpendicular = fdctrl->fifo[1] & 0x7;
  1593. /* No result back */
  1594. fdctrl_reset_fifo(fdctrl);
  1595. }
  1596. static void fdctrl_handle_configure(FDCtrl *fdctrl, int direction)
  1597. {
  1598. fdctrl->config = fdctrl->fifo[2];
  1599. fdctrl->precomp_trk = fdctrl->fifo[3];
  1600. /* No result back */
  1601. fdctrl_reset_fifo(fdctrl);
  1602. }
  1603. static void fdctrl_handle_powerdown_mode(FDCtrl *fdctrl, int direction)
  1604. {
  1605. fdctrl->pwrd = fdctrl->fifo[1];
  1606. fdctrl->fifo[0] = fdctrl->fifo[1];
  1607. fdctrl_set_fifo(fdctrl, 1, 0);
  1608. }
  1609. static void fdctrl_handle_option(FDCtrl *fdctrl, int direction)
  1610. {
  1611. /* No result back */
  1612. fdctrl_reset_fifo(fdctrl);
  1613. }
  1614. static void fdctrl_handle_drive_specification_command(FDCtrl *fdctrl, int direction)
  1615. {
  1616. FDrive *cur_drv = get_cur_drv(fdctrl);
  1617. if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x80) {
  1618. /* Command parameters done */
  1619. if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x40) {
  1620. fdctrl->fifo[0] = fdctrl->fifo[1];
  1621. fdctrl->fifo[2] = 0;
  1622. fdctrl->fifo[3] = 0;
  1623. fdctrl_set_fifo(fdctrl, 4, 0);
  1624. } else {
  1625. fdctrl_reset_fifo(fdctrl);
  1626. }
  1627. } else if (fdctrl->data_len > 7) {
  1628. /* ERROR */
  1629. fdctrl->fifo[0] = 0x80 |
  1630. (cur_drv->head << 2) | GET_CUR_DRV(fdctrl);
  1631. fdctrl_set_fifo(fdctrl, 1, 0);
  1632. }
  1633. }
  1634. static void fdctrl_handle_relative_seek_in(FDCtrl *fdctrl, int direction)
  1635. {
  1636. FDrive *cur_drv;
  1637. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1638. cur_drv = get_cur_drv(fdctrl);
  1639. if (fdctrl->fifo[2] + cur_drv->track >= cur_drv->max_track) {
  1640. fd_seek(cur_drv, cur_drv->head, cur_drv->max_track - 1,
  1641. cur_drv->sect, 1);
  1642. } else {
  1643. fd_seek(cur_drv, cur_drv->head,
  1644. cur_drv->track + fdctrl->fifo[2], cur_drv->sect, 1);
  1645. }
  1646. fdctrl_reset_fifo(fdctrl);
  1647. /* Raise Interrupt */
  1648. fdctrl_raise_irq(fdctrl, FD_SR0_SEEK);
  1649. }
  1650. static void fdctrl_handle_relative_seek_out(FDCtrl *fdctrl, int direction)
  1651. {
  1652. FDrive *cur_drv;
  1653. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1654. cur_drv = get_cur_drv(fdctrl);
  1655. if (fdctrl->fifo[2] > cur_drv->track) {
  1656. fd_seek(cur_drv, cur_drv->head, 0, cur_drv->sect, 1);
  1657. } else {
  1658. fd_seek(cur_drv, cur_drv->head,
  1659. cur_drv->track - fdctrl->fifo[2], cur_drv->sect, 1);
  1660. }
  1661. fdctrl_reset_fifo(fdctrl);
  1662. /* Raise Interrupt */
  1663. fdctrl_raise_irq(fdctrl, FD_SR0_SEEK);
  1664. }
  1665. static const struct {
  1666. uint8_t value;
  1667. uint8_t mask;
  1668. const char* name;
  1669. int parameters;
  1670. void (*handler)(FDCtrl *fdctrl, int direction);
  1671. int direction;
  1672. } handlers[] = {
  1673. { FD_CMD_READ, 0x1f, "READ", 8, fdctrl_start_transfer, FD_DIR_READ },
  1674. { FD_CMD_WRITE, 0x3f, "WRITE", 8, fdctrl_start_transfer, FD_DIR_WRITE },
  1675. { FD_CMD_SEEK, 0xff, "SEEK", 2, fdctrl_handle_seek },
  1676. { FD_CMD_SENSE_INTERRUPT_STATUS, 0xff, "SENSE INTERRUPT STATUS", 0, fdctrl_handle_sense_interrupt_status },
  1677. { FD_CMD_RECALIBRATE, 0xff, "RECALIBRATE", 1, fdctrl_handle_recalibrate },
  1678. { FD_CMD_FORMAT_TRACK, 0xbf, "FORMAT TRACK", 5, fdctrl_handle_format_track },
  1679. { FD_CMD_READ_TRACK, 0xbf, "READ TRACK", 8, fdctrl_start_transfer, FD_DIR_READ },
  1680. { FD_CMD_RESTORE, 0xff, "RESTORE", 17, fdctrl_handle_restore }, /* part of READ DELETED DATA */
  1681. { FD_CMD_SAVE, 0xff, "SAVE", 0, fdctrl_handle_save }, /* part of READ DELETED DATA */
  1682. { FD_CMD_READ_DELETED, 0x1f, "READ DELETED DATA", 8, fdctrl_start_transfer_del, FD_DIR_READ },
  1683. { FD_CMD_SCAN_EQUAL, 0x1f, "SCAN EQUAL", 8, fdctrl_start_transfer, FD_DIR_SCANE },
  1684. { FD_CMD_VERIFY, 0x1f, "VERIFY", 8, fdctrl_unimplemented },
  1685. { FD_CMD_SCAN_LOW_OR_EQUAL, 0x1f, "SCAN LOW OR EQUAL", 8, fdctrl_start_transfer, FD_DIR_SCANL },
  1686. { FD_CMD_SCAN_HIGH_OR_EQUAL, 0x1f, "SCAN HIGH OR EQUAL", 8, fdctrl_start_transfer, FD_DIR_SCANH },
  1687. { FD_CMD_WRITE_DELETED, 0x3f, "WRITE DELETED DATA", 8, fdctrl_start_transfer_del, FD_DIR_WRITE },
  1688. { FD_CMD_READ_ID, 0xbf, "READ ID", 1, fdctrl_handle_readid },
  1689. { FD_CMD_SPECIFY, 0xff, "SPECIFY", 2, fdctrl_handle_specify },
  1690. { FD_CMD_SENSE_DRIVE_STATUS, 0xff, "SENSE DRIVE STATUS", 1, fdctrl_handle_sense_drive_status },
  1691. { FD_CMD_PERPENDICULAR_MODE, 0xff, "PERPENDICULAR MODE", 1, fdctrl_handle_perpendicular_mode },
  1692. { FD_CMD_CONFIGURE, 0xff, "CONFIGURE", 3, fdctrl_handle_configure },
  1693. { FD_CMD_POWERDOWN_MODE, 0xff, "POWERDOWN MODE", 2, fdctrl_handle_powerdown_mode },
  1694. { FD_CMD_OPTION, 0xff, "OPTION", 1, fdctrl_handle_option },
  1695. { FD_CMD_DRIVE_SPECIFICATION_COMMAND, 0xff, "DRIVE SPECIFICATION COMMAND", 5, fdctrl_handle_drive_specification_command },
  1696. { FD_CMD_RELATIVE_SEEK_OUT, 0xff, "RELATIVE SEEK OUT", 2, fdctrl_handle_relative_seek_out },
  1697. { FD_CMD_FORMAT_AND_WRITE, 0xff, "FORMAT AND WRITE", 10, fdctrl_unimplemented },
  1698. { FD_CMD_RELATIVE_SEEK_IN, 0xff, "RELATIVE SEEK IN", 2, fdctrl_handle_relative_seek_in },
  1699. { FD_CMD_LOCK, 0x7f, "LOCK", 0, fdctrl_handle_lock },
  1700. { FD_CMD_DUMPREG, 0xff, "DUMPREG", 0, fdctrl_handle_dumpreg },
  1701. { FD_CMD_VERSION, 0xff, "VERSION", 0, fdctrl_handle_version },
  1702. { FD_CMD_PART_ID, 0xff, "PART ID", 0, fdctrl_handle_partid },
  1703. { FD_CMD_WRITE, 0x1f, "WRITE (BeOS)", 8, fdctrl_start_transfer, FD_DIR_WRITE }, /* not in specification ; BeOS 4.5 bug */
  1704. { 0, 0, "unknown", 0, fdctrl_unimplemented }, /* default handler */
  1705. };
  1706. /* Associate command to an index in the 'handlers' array */
  1707. static uint8_t command_to_handler[256];
  1708. static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value)
  1709. {
  1710. FDrive *cur_drv;
  1711. int pos;
  1712. /* Reset mode */
  1713. if (!(fdctrl->dor & FD_DOR_nRESET)) {
  1714. FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
  1715. return;
  1716. }
  1717. if (!(fdctrl->msr & FD_MSR_RQM) || (fdctrl->msr & FD_MSR_DIO)) {
  1718. FLOPPY_DPRINTF("error: controller not ready for writing\n");
  1719. return;
  1720. }
  1721. fdctrl->dsr &= ~FD_DSR_PWRDOWN;
  1722. /* Is it write command time ? */
  1723. if (fdctrl->msr & FD_MSR_NONDMA) {
  1724. /* FIFO data write */
  1725. pos = fdctrl->data_pos++;
  1726. pos %= FD_SECTOR_LEN;
  1727. fdctrl->fifo[pos] = value;
  1728. if (pos == FD_SECTOR_LEN - 1 ||
  1729. fdctrl->data_pos == fdctrl->data_len) {
  1730. cur_drv = get_cur_drv(fdctrl);
  1731. if (bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) {
  1732. FLOPPY_DPRINTF("error writing sector %d\n",
  1733. fd_sector(cur_drv));
  1734. return;
  1735. }
  1736. if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) {
  1737. FLOPPY_DPRINTF("error seeking to next sector %d\n",
  1738. fd_sector(cur_drv));
  1739. return;
  1740. }
  1741. }
  1742. /* Switch from transfer mode to status mode
  1743. * then from status mode to command mode
  1744. */
  1745. if (fdctrl->data_pos == fdctrl->data_len)
  1746. fdctrl_stop_transfer(fdctrl, FD_SR0_SEEK, 0x00, 0x00);
  1747. return;
  1748. }
  1749. if (fdctrl->data_pos == 0) {
  1750. /* Command */
  1751. pos = command_to_handler[value & 0xff];
  1752. FLOPPY_DPRINTF("%s command\n", handlers[pos].name);
  1753. fdctrl->data_len = handlers[pos].parameters + 1;
  1754. fdctrl->msr |= FD_MSR_CMDBUSY;
  1755. }
  1756. FLOPPY_DPRINTF("%s: %02x\n", __func__, value);
  1757. fdctrl->fifo[fdctrl->data_pos++] = value;
  1758. if (fdctrl->data_pos == fdctrl->data_len) {
  1759. /* We now have all parameters
  1760. * and will be able to treat the command
  1761. */
  1762. if (fdctrl->data_state & FD_STATE_FORMAT) {
  1763. fdctrl_format_sector(fdctrl);
  1764. return;
  1765. }
  1766. pos = command_to_handler[fdctrl->fifo[0] & 0xff];
  1767. FLOPPY_DPRINTF("treat %s command\n", handlers[pos].name);
  1768. (*handlers[pos].handler)(fdctrl, handlers[pos].direction);
  1769. }
  1770. }
  1771. static void fdctrl_result_timer(void *opaque)
  1772. {
  1773. FDCtrl *fdctrl = opaque;
  1774. FDrive *cur_drv = get_cur_drv(fdctrl);
  1775. /* Pretend we are spinning.
  1776. * This is needed for Coherent, which uses READ ID to check for
  1777. * sector interleaving.
  1778. */
  1779. if (cur_drv->last_sect != 0) {
  1780. cur_drv->sect = (cur_drv->sect % cur_drv->last_sect) + 1;
  1781. }
  1782. /* READ_ID can't automatically succeed! */
  1783. if (fdctrl->check_media_rate &&
  1784. (fdctrl->dsr & FD_DSR_DRATEMASK) != cur_drv->media_rate) {
  1785. FLOPPY_DPRINTF("read id rate mismatch (fdc=%d, media=%d)\n",
  1786. fdctrl->dsr & FD_DSR_DRATEMASK, cur_drv->media_rate);
  1787. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA, 0x00);
  1788. } else {
  1789. fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
  1790. }
  1791. }
  1792. static void fdctrl_change_cb(void *opaque, bool load)
  1793. {
  1794. FDrive *drive = opaque;
  1795. drive->media_changed = 1;
  1796. fd_revalidate(drive);
  1797. }
  1798. static const BlockDevOps fdctrl_block_ops = {
  1799. .change_media_cb = fdctrl_change_cb,
  1800. };
  1801. /* Init functions */
  1802. static int fdctrl_connect_drives(FDCtrl *fdctrl)
  1803. {
  1804. unsigned int i;
  1805. FDrive *drive;
  1806. for (i = 0; i < MAX_FD; i++) {
  1807. drive = &fdctrl->drives[i];
  1808. drive->fdctrl = fdctrl;
  1809. if (drive->bs) {
  1810. if (bdrv_get_on_error(drive->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
  1811. error_report("fdc doesn't support drive option werror");
  1812. return -1;
  1813. }
  1814. if (bdrv_get_on_error(drive->bs, 1) != BLOCK_ERR_REPORT) {
  1815. error_report("fdc doesn't support drive option rerror");
  1816. return -1;
  1817. }
  1818. }
  1819. fd_init(drive);
  1820. fdctrl_change_cb(drive, 0);
  1821. if (drive->bs) {
  1822. bdrv_set_dev_ops(drive->bs, &fdctrl_block_ops, drive);
  1823. }
  1824. }
  1825. return 0;
  1826. }
  1827. ISADevice *fdctrl_init_isa(ISABus *bus, DriveInfo **fds)
  1828. {
  1829. ISADevice *dev;
  1830. dev = isa_try_create(bus, "isa-fdc");
  1831. if (!dev) {
  1832. return NULL;
  1833. }
  1834. if (fds[0]) {
  1835. qdev_prop_set_drive_nofail(&dev->qdev, "driveA", fds[0]->bdrv);
  1836. }
  1837. if (fds[1]) {
  1838. qdev_prop_set_drive_nofail(&dev->qdev, "driveB", fds[1]->bdrv);
  1839. }
  1840. qdev_init_nofail(&dev->qdev);
  1841. return dev;
  1842. }
  1843. void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
  1844. target_phys_addr_t mmio_base, DriveInfo **fds)
  1845. {
  1846. FDCtrl *fdctrl;
  1847. DeviceState *dev;
  1848. FDCtrlSysBus *sys;
  1849. dev = qdev_create(NULL, "sysbus-fdc");
  1850. sys = DO_UPCAST(FDCtrlSysBus, busdev.qdev, dev);
  1851. fdctrl = &sys->state;
  1852. fdctrl->dma_chann = dma_chann; /* FIXME */
  1853. if (fds[0]) {
  1854. qdev_prop_set_drive_nofail(dev, "driveA", fds[0]->bdrv);
  1855. }
  1856. if (fds[1]) {
  1857. qdev_prop_set_drive_nofail(dev, "driveB", fds[1]->bdrv);
  1858. }
  1859. qdev_init_nofail(dev);
  1860. sysbus_connect_irq(&sys->busdev, 0, irq);
  1861. sysbus_mmio_map(&sys->busdev, 0, mmio_base);
  1862. }
  1863. void sun4m_fdctrl_init(qemu_irq irq, target_phys_addr_t io_base,
  1864. DriveInfo **fds, qemu_irq *fdc_tc)
  1865. {
  1866. DeviceState *dev;
  1867. FDCtrlSysBus *sys;
  1868. dev = qdev_create(NULL, "SUNW,fdtwo");
  1869. if (fds[0]) {
  1870. qdev_prop_set_drive_nofail(dev, "drive", fds[0]->bdrv);
  1871. }
  1872. qdev_init_nofail(dev);
  1873. sys = DO_UPCAST(FDCtrlSysBus, busdev.qdev, dev);
  1874. sysbus_connect_irq(&sys->busdev, 0, irq);
  1875. sysbus_mmio_map(&sys->busdev, 0, io_base);
  1876. *fdc_tc = qdev_get_gpio_in(dev, 0);
  1877. }
  1878. static int fdctrl_init_common(FDCtrl *fdctrl)
  1879. {
  1880. int i, j;
  1881. static int command_tables_inited = 0;
  1882. /* Fill 'command_to_handler' lookup table */
  1883. if (!command_tables_inited) {
  1884. command_tables_inited = 1;
  1885. for (i = ARRAY_SIZE(handlers) - 1; i >= 0; i--) {
  1886. for (j = 0; j < sizeof(command_to_handler); j++) {
  1887. if ((j & handlers[i].mask) == handlers[i].value) {
  1888. command_to_handler[j] = i;
  1889. }
  1890. }
  1891. }
  1892. }
  1893. FLOPPY_DPRINTF("init controller\n");
  1894. fdctrl->fifo = qemu_memalign(512, FD_SECTOR_LEN);
  1895. fdctrl->fifo_size = 512;
  1896. fdctrl->result_timer = qemu_new_timer_ns(vm_clock,
  1897. fdctrl_result_timer, fdctrl);
  1898. fdctrl->version = 0x90; /* Intel 82078 controller */
  1899. fdctrl->config = FD_CONFIG_EIS | FD_CONFIG_EFIFO; /* Implicit seek, polling & FIFO enabled */
  1900. fdctrl->num_floppies = MAX_FD;
  1901. if (fdctrl->dma_chann != -1)
  1902. DMA_register_channel(fdctrl->dma_chann, &fdctrl_transfer_handler, fdctrl);
  1903. return fdctrl_connect_drives(fdctrl);
  1904. }
  1905. static const MemoryRegionPortio fdc_portio_list[] = {
  1906. { 1, 5, 1, .read = fdctrl_read, .write = fdctrl_write },
  1907. { 7, 1, 1, .read = fdctrl_read, .write = fdctrl_write },
  1908. PORTIO_END_OF_LIST(),
  1909. };
  1910. static int isabus_fdc_init1(ISADevice *dev)
  1911. {
  1912. FDCtrlISABus *isa = DO_UPCAST(FDCtrlISABus, busdev, dev);
  1913. FDCtrl *fdctrl = &isa->state;
  1914. int ret;
  1915. isa_register_portio_list(dev, isa->iobase, fdc_portio_list, fdctrl, "fdc");
  1916. isa_init_irq(&isa->busdev, &fdctrl->irq, isa->irq);
  1917. fdctrl->dma_chann = isa->dma;
  1918. qdev_set_legacy_instance_id(&dev->qdev, isa->iobase, 2);
  1919. ret = fdctrl_init_common(fdctrl);
  1920. add_boot_device_path(isa->bootindexA, &dev->qdev, "/floppy@0");
  1921. add_boot_device_path(isa->bootindexB, &dev->qdev, "/floppy@1");
  1922. return ret;
  1923. }
  1924. static int sysbus_fdc_init1(SysBusDevice *dev)
  1925. {
  1926. FDCtrlSysBus *sys = DO_UPCAST(FDCtrlSysBus, busdev, dev);
  1927. FDCtrl *fdctrl = &sys->state;
  1928. int ret;
  1929. memory_region_init_io(&fdctrl->iomem, &fdctrl_mem_ops, fdctrl, "fdc", 0x08);
  1930. sysbus_init_mmio(dev, &fdctrl->iomem);
  1931. sysbus_init_irq(dev, &fdctrl->irq);
  1932. qdev_init_gpio_in(&dev->qdev, fdctrl_handle_tc, 1);
  1933. fdctrl->dma_chann = -1;
  1934. qdev_set_legacy_instance_id(&dev->qdev, 0 /* io */, 2); /* FIXME */
  1935. ret = fdctrl_init_common(fdctrl);
  1936. return ret;
  1937. }
  1938. static int sun4m_fdc_init1(SysBusDevice *dev)
  1939. {
  1940. FDCtrl *fdctrl = &(FROM_SYSBUS(FDCtrlSysBus, dev)->state);
  1941. memory_region_init_io(&fdctrl->iomem, &fdctrl_mem_strict_ops, fdctrl,
  1942. "fdctrl", 0x08);
  1943. sysbus_init_mmio(dev, &fdctrl->iomem);
  1944. sysbus_init_irq(dev, &fdctrl->irq);
  1945. qdev_init_gpio_in(&dev->qdev, fdctrl_handle_tc, 1);
  1946. fdctrl->sun4m = 1;
  1947. qdev_set_legacy_instance_id(&dev->qdev, 0 /* io */, 2); /* FIXME */
  1948. return fdctrl_init_common(fdctrl);
  1949. }
  1950. FDriveType isa_fdc_get_drive_type(ISADevice *fdc, int i)
  1951. {
  1952. FDCtrlISABus *isa = DO_UPCAST(FDCtrlISABus, busdev, fdc);
  1953. return isa->state.drives[i].drive;
  1954. }
  1955. static const VMStateDescription vmstate_isa_fdc ={
  1956. .name = "fdc",
  1957. .version_id = 2,
  1958. .minimum_version_id = 2,
  1959. .fields = (VMStateField []) {
  1960. VMSTATE_STRUCT(state, FDCtrlISABus, 0, vmstate_fdc, FDCtrl),
  1961. VMSTATE_END_OF_LIST()
  1962. }
  1963. };
  1964. static Property isa_fdc_properties[] = {
  1965. DEFINE_PROP_HEX32("iobase", FDCtrlISABus, iobase, 0x3f0),
  1966. DEFINE_PROP_UINT32("irq", FDCtrlISABus, irq, 6),
  1967. DEFINE_PROP_UINT32("dma", FDCtrlISABus, dma, 2),
  1968. DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.drives[0].bs),
  1969. DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.drives[1].bs),
  1970. DEFINE_PROP_INT32("bootindexA", FDCtrlISABus, bootindexA, -1),
  1971. DEFINE_PROP_INT32("bootindexB", FDCtrlISABus, bootindexB, -1),
  1972. DEFINE_PROP_BIT("check_media_rate", FDCtrlISABus, state.check_media_rate,
  1973. 0, true),
  1974. DEFINE_PROP_END_OF_LIST(),
  1975. };
  1976. static void isabus_fdc_class_init1(ObjectClass *klass, void *data)
  1977. {
  1978. DeviceClass *dc = DEVICE_CLASS(klass);
  1979. ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
  1980. ic->init = isabus_fdc_init1;
  1981. dc->fw_name = "fdc";
  1982. dc->no_user = 1;
  1983. dc->reset = fdctrl_external_reset_isa;
  1984. dc->vmsd = &vmstate_isa_fdc;
  1985. dc->props = isa_fdc_properties;
  1986. }
  1987. static TypeInfo isa_fdc_info = {
  1988. .name = "isa-fdc",
  1989. .parent = TYPE_ISA_DEVICE,
  1990. .instance_size = sizeof(FDCtrlISABus),
  1991. .class_init = isabus_fdc_class_init1,
  1992. };
  1993. static const VMStateDescription vmstate_sysbus_fdc ={
  1994. .name = "fdc",
  1995. .version_id = 2,
  1996. .minimum_version_id = 2,
  1997. .fields = (VMStateField []) {
  1998. VMSTATE_STRUCT(state, FDCtrlSysBus, 0, vmstate_fdc, FDCtrl),
  1999. VMSTATE_END_OF_LIST()
  2000. }
  2001. };
  2002. static Property sysbus_fdc_properties[] = {
  2003. DEFINE_PROP_DRIVE("driveA", FDCtrlSysBus, state.drives[0].bs),
  2004. DEFINE_PROP_DRIVE("driveB", FDCtrlSysBus, state.drives[1].bs),
  2005. DEFINE_PROP_END_OF_LIST(),
  2006. };
  2007. static void sysbus_fdc_class_init(ObjectClass *klass, void *data)
  2008. {
  2009. DeviceClass *dc = DEVICE_CLASS(klass);
  2010. SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
  2011. k->init = sysbus_fdc_init1;
  2012. dc->reset = fdctrl_external_reset_sysbus;
  2013. dc->vmsd = &vmstate_sysbus_fdc;
  2014. dc->props = sysbus_fdc_properties;
  2015. }
  2016. static TypeInfo sysbus_fdc_info = {
  2017. .name = "sysbus-fdc",
  2018. .parent = TYPE_SYS_BUS_DEVICE,
  2019. .instance_size = sizeof(FDCtrlSysBus),
  2020. .class_init = sysbus_fdc_class_init,
  2021. };
  2022. static Property sun4m_fdc_properties[] = {
  2023. DEFINE_PROP_DRIVE("drive", FDCtrlSysBus, state.drives[0].bs),
  2024. DEFINE_PROP_END_OF_LIST(),
  2025. };
  2026. static void sun4m_fdc_class_init(ObjectClass *klass, void *data)
  2027. {
  2028. DeviceClass *dc = DEVICE_CLASS(klass);
  2029. SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
  2030. k->init = sun4m_fdc_init1;
  2031. dc->reset = fdctrl_external_reset_sysbus;
  2032. dc->vmsd = &vmstate_sysbus_fdc;
  2033. dc->props = sun4m_fdc_properties;
  2034. }
  2035. static TypeInfo sun4m_fdc_info = {
  2036. .name = "SUNW,fdtwo",
  2037. .parent = TYPE_SYS_BUS_DEVICE,
  2038. .instance_size = sizeof(FDCtrlSysBus),
  2039. .class_init = sun4m_fdc_class_init,
  2040. };
  2041. static void fdc_register_types(void)
  2042. {
  2043. type_register_static(&isa_fdc_info);
  2044. type_register_static(&sysbus_fdc_info);
  2045. type_register_static(&sun4m_fdc_info);
  2046. }
  2047. type_init(fdc_register_types)