cirrus_vga.c 98 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028
  1. /*
  2. * QEMU Cirrus CLGD 54xx VGA Emulator.
  3. *
  4. * Copyright (c) 2004 Fabrice Bellard
  5. * Copyright (c) 2004 Makoto Suzuki (suzu)
  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. * Reference: Finn Thogersons' VGADOC4b:
  27. *
  28. * http://web.archive.org/web/20021019054927/http://home.worldonline.dk/finth/
  29. *
  30. * VGADOC4b.ZIP content available at:
  31. *
  32. * https://pdos.csail.mit.edu/6.828/2005/readings/hardware/vgadoc
  33. */
  34. #include "qemu/osdep.h"
  35. #include "qemu/module.h"
  36. #include "qemu/units.h"
  37. #include "qemu/log.h"
  38. #include "sysemu/reset.h"
  39. #include "qapi/error.h"
  40. #include "trace.h"
  41. #include "hw/pci/pci_device.h"
  42. #include "hw/qdev-properties.h"
  43. #include "migration/vmstate.h"
  44. #include "ui/pixel_ops.h"
  45. #include "cirrus_vga_internal.h"
  46. #include "qom/object.h"
  47. #include "ui/console.h"
  48. /*
  49. * TODO:
  50. * - destination write mask support not complete (bits 5..7)
  51. * - optimize linear mappings
  52. * - optimize bitblt functions
  53. */
  54. //#define DEBUG_CIRRUS
  55. /***************************************
  56. *
  57. * definitions
  58. *
  59. ***************************************/
  60. // sequencer 0x07
  61. #define CIRRUS_SR7_BPP_VGA 0x00
  62. #define CIRRUS_SR7_BPP_SVGA 0x01
  63. #define CIRRUS_SR7_BPP_MASK 0x0e
  64. #define CIRRUS_SR7_BPP_8 0x00
  65. #define CIRRUS_SR7_BPP_16_DOUBLEVCLK 0x02
  66. #define CIRRUS_SR7_BPP_24 0x04
  67. #define CIRRUS_SR7_BPP_16 0x06
  68. #define CIRRUS_SR7_BPP_32 0x08
  69. #define CIRRUS_SR7_ISAADDR_MASK 0xe0
  70. // sequencer 0x0f
  71. #define CIRRUS_MEMSIZE_512k 0x08
  72. #define CIRRUS_MEMSIZE_1M 0x10
  73. #define CIRRUS_MEMSIZE_2M 0x18
  74. #define CIRRUS_MEMFLAGS_BANKSWITCH 0x80 // bank switching is enabled.
  75. // sequencer 0x12
  76. #define CIRRUS_CURSOR_SHOW 0x01
  77. #define CIRRUS_CURSOR_HIDDENPEL 0x02
  78. #define CIRRUS_CURSOR_LARGE 0x04 // 64x64 if set, 32x32 if clear
  79. // sequencer 0x17
  80. #define CIRRUS_BUSTYPE_VLBFAST 0x10
  81. #define CIRRUS_BUSTYPE_PCI 0x20
  82. #define CIRRUS_BUSTYPE_VLBSLOW 0x30
  83. #define CIRRUS_BUSTYPE_ISA 0x38
  84. #define CIRRUS_MMIO_ENABLE 0x04
  85. #define CIRRUS_MMIO_USE_PCIADDR 0x40 // 0xb8000 if cleared.
  86. #define CIRRUS_MEMSIZEEXT_DOUBLE 0x80
  87. // control 0x0b
  88. #define CIRRUS_BANKING_DUAL 0x01
  89. #define CIRRUS_BANKING_GRANULARITY_16K 0x20 // set:16k, clear:4k
  90. // control 0x30
  91. #define CIRRUS_BLTMODE_BACKWARDS 0x01
  92. #define CIRRUS_BLTMODE_MEMSYSDEST 0x02
  93. #define CIRRUS_BLTMODE_MEMSYSSRC 0x04
  94. #define CIRRUS_BLTMODE_TRANSPARENTCOMP 0x08
  95. #define CIRRUS_BLTMODE_PATTERNCOPY 0x40
  96. #define CIRRUS_BLTMODE_COLOREXPAND 0x80
  97. #define CIRRUS_BLTMODE_PIXELWIDTHMASK 0x30
  98. #define CIRRUS_BLTMODE_PIXELWIDTH8 0x00
  99. #define CIRRUS_BLTMODE_PIXELWIDTH16 0x10
  100. #define CIRRUS_BLTMODE_PIXELWIDTH24 0x20
  101. #define CIRRUS_BLTMODE_PIXELWIDTH32 0x30
  102. // control 0x31
  103. #define CIRRUS_BLT_BUSY 0x01
  104. #define CIRRUS_BLT_START 0x02
  105. #define CIRRUS_BLT_RESET 0x04
  106. #define CIRRUS_BLT_FIFOUSED 0x10
  107. #define CIRRUS_BLT_AUTOSTART 0x80
  108. // control 0x32
  109. #define CIRRUS_ROP_0 0x00
  110. #define CIRRUS_ROP_SRC_AND_DST 0x05
  111. #define CIRRUS_ROP_NOP 0x06
  112. #define CIRRUS_ROP_SRC_AND_NOTDST 0x09
  113. #define CIRRUS_ROP_NOTDST 0x0b
  114. #define CIRRUS_ROP_SRC 0x0d
  115. #define CIRRUS_ROP_1 0x0e
  116. #define CIRRUS_ROP_NOTSRC_AND_DST 0x50
  117. #define CIRRUS_ROP_SRC_XOR_DST 0x59
  118. #define CIRRUS_ROP_SRC_OR_DST 0x6d
  119. #define CIRRUS_ROP_NOTSRC_OR_NOTDST 0x90
  120. #define CIRRUS_ROP_SRC_NOTXOR_DST 0x95
  121. #define CIRRUS_ROP_SRC_OR_NOTDST 0xad
  122. #define CIRRUS_ROP_NOTSRC 0xd0
  123. #define CIRRUS_ROP_NOTSRC_OR_DST 0xd6
  124. #define CIRRUS_ROP_NOTSRC_AND_NOTDST 0xda
  125. #define CIRRUS_ROP_NOP_INDEX 2
  126. #define CIRRUS_ROP_SRC_INDEX 5
  127. // control 0x33
  128. #define CIRRUS_BLTMODEEXT_SOLIDFILL 0x04
  129. #define CIRRUS_BLTMODEEXT_COLOREXPINV 0x02
  130. #define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01
  131. // memory-mapped IO
  132. #define CIRRUS_MMIO_BLTBGCOLOR 0x00 // dword
  133. #define CIRRUS_MMIO_BLTFGCOLOR 0x04 // dword
  134. #define CIRRUS_MMIO_BLTWIDTH 0x08 // word
  135. #define CIRRUS_MMIO_BLTHEIGHT 0x0a // word
  136. #define CIRRUS_MMIO_BLTDESTPITCH 0x0c // word
  137. #define CIRRUS_MMIO_BLTSRCPITCH 0x0e // word
  138. #define CIRRUS_MMIO_BLTDESTADDR 0x10 // dword
  139. #define CIRRUS_MMIO_BLTSRCADDR 0x14 // dword
  140. #define CIRRUS_MMIO_BLTWRITEMASK 0x17 // byte
  141. #define CIRRUS_MMIO_BLTMODE 0x18 // byte
  142. #define CIRRUS_MMIO_BLTROP 0x1a // byte
  143. #define CIRRUS_MMIO_BLTMODEEXT 0x1b // byte
  144. #define CIRRUS_MMIO_BLTTRANSPARENTCOLOR 0x1c // word?
  145. #define CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK 0x20 // word?
  146. #define CIRRUS_MMIO_LINEARDRAW_START_X 0x24 // word
  147. #define CIRRUS_MMIO_LINEARDRAW_START_Y 0x26 // word
  148. #define CIRRUS_MMIO_LINEARDRAW_END_X 0x28 // word
  149. #define CIRRUS_MMIO_LINEARDRAW_END_Y 0x2a // word
  150. #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_INC 0x2c // byte
  151. #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ROLLOVER 0x2d // byte
  152. #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_MASK 0x2e // byte
  153. #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ACCUM 0x2f // byte
  154. #define CIRRUS_MMIO_BRESENHAM_K1 0x30 // word
  155. #define CIRRUS_MMIO_BRESENHAM_K3 0x32 // word
  156. #define CIRRUS_MMIO_BRESENHAM_ERROR 0x34 // word
  157. #define CIRRUS_MMIO_BRESENHAM_DELTA_MAJOR 0x36 // word
  158. #define CIRRUS_MMIO_BRESENHAM_DIRECTION 0x38 // byte
  159. #define CIRRUS_MMIO_LINEDRAW_MODE 0x39 // byte
  160. #define CIRRUS_MMIO_BLTSTATUS 0x40 // byte
  161. #define CIRRUS_PNPMMIO_SIZE 0x1000
  162. typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
  163. uint32_t dstaddr, int dst_pitch,
  164. int width, int height);
  165. struct PCICirrusVGAState {
  166. PCIDevice dev;
  167. CirrusVGAState cirrus_vga;
  168. };
  169. #define TYPE_PCI_CIRRUS_VGA "cirrus-vga"
  170. OBJECT_DECLARE_SIMPLE_TYPE(PCICirrusVGAState, PCI_CIRRUS_VGA)
  171. static uint8_t rop_to_index[256];
  172. /***************************************
  173. *
  174. * prototypes.
  175. *
  176. ***************************************/
  177. static void cirrus_bitblt_reset(CirrusVGAState *s);
  178. static void cirrus_update_memory_access(CirrusVGAState *s);
  179. /***************************************
  180. *
  181. * raster operations
  182. *
  183. ***************************************/
  184. static bool blit_region_is_unsafe(struct CirrusVGAState *s,
  185. int32_t pitch, int32_t addr)
  186. {
  187. if (!pitch) {
  188. return true;
  189. }
  190. if (pitch < 0) {
  191. int64_t min = addr
  192. + ((int64_t)s->cirrus_blt_height - 1) * pitch
  193. - s->cirrus_blt_width;
  194. if (min < -1 || addr >= s->vga.vram_size) {
  195. return true;
  196. }
  197. } else {
  198. int64_t max = addr
  199. + ((int64_t)s->cirrus_blt_height-1) * pitch
  200. + s->cirrus_blt_width;
  201. if (max > s->vga.vram_size) {
  202. return true;
  203. }
  204. }
  205. return false;
  206. }
  207. static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only)
  208. {
  209. /* should be the case, see cirrus_bitblt_start */
  210. assert(s->cirrus_blt_width > 0);
  211. assert(s->cirrus_blt_height > 0);
  212. if (s->cirrus_blt_width > CIRRUS_BLTBUFSIZE) {
  213. return true;
  214. }
  215. if (blit_region_is_unsafe(s, s->cirrus_blt_dstpitch,
  216. s->cirrus_blt_dstaddr)) {
  217. return true;
  218. }
  219. if (dst_only) {
  220. return false;
  221. }
  222. if (blit_region_is_unsafe(s, s->cirrus_blt_srcpitch,
  223. s->cirrus_blt_srcaddr)) {
  224. return true;
  225. }
  226. return false;
  227. }
  228. static void cirrus_bitblt_rop_nop(CirrusVGAState *s,
  229. uint32_t dstaddr, uint32_t srcaddr,
  230. int dstpitch,int srcpitch,
  231. int bltwidth,int bltheight)
  232. {
  233. }
  234. static void cirrus_bitblt_fill_nop(CirrusVGAState *s,
  235. uint32_t dstaddr,
  236. int dstpitch, int bltwidth,int bltheight)
  237. {
  238. }
  239. static inline uint8_t cirrus_src(CirrusVGAState *s, uint32_t srcaddr)
  240. {
  241. if (s->cirrus_srccounter) {
  242. /* cputovideo */
  243. return s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1)];
  244. } else {
  245. /* videotovideo */
  246. return s->vga.vram_ptr[srcaddr & s->cirrus_addr_mask];
  247. }
  248. }
  249. static inline uint16_t cirrus_src16(CirrusVGAState *s, uint32_t srcaddr)
  250. {
  251. uint16_t *src;
  252. if (s->cirrus_srccounter) {
  253. /* cputovideo */
  254. src = (void *)&s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1) & ~1];
  255. } else {
  256. /* videotovideo */
  257. src = (void *)&s->vga.vram_ptr[srcaddr & s->cirrus_addr_mask & ~1];
  258. }
  259. return *src;
  260. }
  261. static inline uint32_t cirrus_src32(CirrusVGAState *s, uint32_t srcaddr)
  262. {
  263. uint32_t *src;
  264. if (s->cirrus_srccounter) {
  265. /* cputovideo */
  266. src = (void *)&s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1) & ~3];
  267. } else {
  268. /* videotovideo */
  269. src = (void *)&s->vga.vram_ptr[srcaddr & s->cirrus_addr_mask & ~3];
  270. }
  271. return *src;
  272. }
  273. #define ROP_NAME 0
  274. #define ROP_FN(d, s) 0
  275. #include "cirrus_vga_rop.h"
  276. #define ROP_NAME src_and_dst
  277. #define ROP_FN(d, s) (s) & (d)
  278. #include "cirrus_vga_rop.h"
  279. #define ROP_NAME src_and_notdst
  280. #define ROP_FN(d, s) (s) & (~(d))
  281. #include "cirrus_vga_rop.h"
  282. #define ROP_NAME notdst
  283. #define ROP_FN(d, s) ~(d)
  284. #include "cirrus_vga_rop.h"
  285. #define ROP_NAME src
  286. #define ROP_FN(d, s) s
  287. #include "cirrus_vga_rop.h"
  288. #define ROP_NAME 1
  289. #define ROP_FN(d, s) ~0
  290. #include "cirrus_vga_rop.h"
  291. #define ROP_NAME notsrc_and_dst
  292. #define ROP_FN(d, s) (~(s)) & (d)
  293. #include "cirrus_vga_rop.h"
  294. #define ROP_NAME src_xor_dst
  295. #define ROP_FN(d, s) (s) ^ (d)
  296. #include "cirrus_vga_rop.h"
  297. #define ROP_NAME src_or_dst
  298. #define ROP_FN(d, s) (s) | (d)
  299. #include "cirrus_vga_rop.h"
  300. #define ROP_NAME notsrc_or_notdst
  301. #define ROP_FN(d, s) (~(s)) | (~(d))
  302. #include "cirrus_vga_rop.h"
  303. #define ROP_NAME src_notxor_dst
  304. #define ROP_FN(d, s) ~((s) ^ (d))
  305. #include "cirrus_vga_rop.h"
  306. #define ROP_NAME src_or_notdst
  307. #define ROP_FN(d, s) (s) | (~(d))
  308. #include "cirrus_vga_rop.h"
  309. #define ROP_NAME notsrc
  310. #define ROP_FN(d, s) (~(s))
  311. #include "cirrus_vga_rop.h"
  312. #define ROP_NAME notsrc_or_dst
  313. #define ROP_FN(d, s) (~(s)) | (d)
  314. #include "cirrus_vga_rop.h"
  315. #define ROP_NAME notsrc_and_notdst
  316. #define ROP_FN(d, s) (~(s)) & (~(d))
  317. #include "cirrus_vga_rop.h"
  318. static const cirrus_bitblt_rop_t cirrus_fwd_rop[16] = {
  319. cirrus_bitblt_rop_fwd_0,
  320. cirrus_bitblt_rop_fwd_src_and_dst,
  321. cirrus_bitblt_rop_nop,
  322. cirrus_bitblt_rop_fwd_src_and_notdst,
  323. cirrus_bitblt_rop_fwd_notdst,
  324. cirrus_bitblt_rop_fwd_src,
  325. cirrus_bitblt_rop_fwd_1,
  326. cirrus_bitblt_rop_fwd_notsrc_and_dst,
  327. cirrus_bitblt_rop_fwd_src_xor_dst,
  328. cirrus_bitblt_rop_fwd_src_or_dst,
  329. cirrus_bitblt_rop_fwd_notsrc_or_notdst,
  330. cirrus_bitblt_rop_fwd_src_notxor_dst,
  331. cirrus_bitblt_rop_fwd_src_or_notdst,
  332. cirrus_bitblt_rop_fwd_notsrc,
  333. cirrus_bitblt_rop_fwd_notsrc_or_dst,
  334. cirrus_bitblt_rop_fwd_notsrc_and_notdst,
  335. };
  336. static const cirrus_bitblt_rop_t cirrus_bkwd_rop[16] = {
  337. cirrus_bitblt_rop_bkwd_0,
  338. cirrus_bitblt_rop_bkwd_src_and_dst,
  339. cirrus_bitblt_rop_nop,
  340. cirrus_bitblt_rop_bkwd_src_and_notdst,
  341. cirrus_bitblt_rop_bkwd_notdst,
  342. cirrus_bitblt_rop_bkwd_src,
  343. cirrus_bitblt_rop_bkwd_1,
  344. cirrus_bitblt_rop_bkwd_notsrc_and_dst,
  345. cirrus_bitblt_rop_bkwd_src_xor_dst,
  346. cirrus_bitblt_rop_bkwd_src_or_dst,
  347. cirrus_bitblt_rop_bkwd_notsrc_or_notdst,
  348. cirrus_bitblt_rop_bkwd_src_notxor_dst,
  349. cirrus_bitblt_rop_bkwd_src_or_notdst,
  350. cirrus_bitblt_rop_bkwd_notsrc,
  351. cirrus_bitblt_rop_bkwd_notsrc_or_dst,
  352. cirrus_bitblt_rop_bkwd_notsrc_and_notdst,
  353. };
  354. #define TRANSP_ROP(name) {\
  355. name ## _8,\
  356. name ## _16,\
  357. }
  358. #define TRANSP_NOP(func) {\
  359. func,\
  360. func,\
  361. }
  362. static const cirrus_bitblt_rop_t cirrus_fwd_transp_rop[16][2] = {
  363. TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_0),
  364. TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_dst),
  365. TRANSP_NOP(cirrus_bitblt_rop_nop),
  366. TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_notdst),
  367. TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notdst),
  368. TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src),
  369. TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_1),
  370. TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_dst),
  371. TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_xor_dst),
  372. TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_dst),
  373. TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_notdst),
  374. TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_notxor_dst),
  375. TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_notdst),
  376. TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc),
  377. TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_dst),
  378. TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_notdst),
  379. };
  380. static const cirrus_bitblt_rop_t cirrus_bkwd_transp_rop[16][2] = {
  381. TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_0),
  382. TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_dst),
  383. TRANSP_NOP(cirrus_bitblt_rop_nop),
  384. TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_notdst),
  385. TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notdst),
  386. TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src),
  387. TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_1),
  388. TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_dst),
  389. TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_xor_dst),
  390. TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_dst),
  391. TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_notdst),
  392. TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_notxor_dst),
  393. TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_notdst),
  394. TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc),
  395. TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_dst),
  396. TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_notdst),
  397. };
  398. #define ROP2(name) {\
  399. name ## _8,\
  400. name ## _16,\
  401. name ## _24,\
  402. name ## _32,\
  403. }
  404. #define ROP_NOP2(func) {\
  405. func,\
  406. func,\
  407. func,\
  408. func,\
  409. }
  410. static const cirrus_bitblt_rop_t cirrus_patternfill[16][4] = {
  411. ROP2(cirrus_patternfill_0),
  412. ROP2(cirrus_patternfill_src_and_dst),
  413. ROP_NOP2(cirrus_bitblt_rop_nop),
  414. ROP2(cirrus_patternfill_src_and_notdst),
  415. ROP2(cirrus_patternfill_notdst),
  416. ROP2(cirrus_patternfill_src),
  417. ROP2(cirrus_patternfill_1),
  418. ROP2(cirrus_patternfill_notsrc_and_dst),
  419. ROP2(cirrus_patternfill_src_xor_dst),
  420. ROP2(cirrus_patternfill_src_or_dst),
  421. ROP2(cirrus_patternfill_notsrc_or_notdst),
  422. ROP2(cirrus_patternfill_src_notxor_dst),
  423. ROP2(cirrus_patternfill_src_or_notdst),
  424. ROP2(cirrus_patternfill_notsrc),
  425. ROP2(cirrus_patternfill_notsrc_or_dst),
  426. ROP2(cirrus_patternfill_notsrc_and_notdst),
  427. };
  428. static const cirrus_bitblt_rop_t cirrus_colorexpand_transp[16][4] = {
  429. ROP2(cirrus_colorexpand_transp_0),
  430. ROP2(cirrus_colorexpand_transp_src_and_dst),
  431. ROP_NOP2(cirrus_bitblt_rop_nop),
  432. ROP2(cirrus_colorexpand_transp_src_and_notdst),
  433. ROP2(cirrus_colorexpand_transp_notdst),
  434. ROP2(cirrus_colorexpand_transp_src),
  435. ROP2(cirrus_colorexpand_transp_1),
  436. ROP2(cirrus_colorexpand_transp_notsrc_and_dst),
  437. ROP2(cirrus_colorexpand_transp_src_xor_dst),
  438. ROP2(cirrus_colorexpand_transp_src_or_dst),
  439. ROP2(cirrus_colorexpand_transp_notsrc_or_notdst),
  440. ROP2(cirrus_colorexpand_transp_src_notxor_dst),
  441. ROP2(cirrus_colorexpand_transp_src_or_notdst),
  442. ROP2(cirrus_colorexpand_transp_notsrc),
  443. ROP2(cirrus_colorexpand_transp_notsrc_or_dst),
  444. ROP2(cirrus_colorexpand_transp_notsrc_and_notdst),
  445. };
  446. static const cirrus_bitblt_rop_t cirrus_colorexpand[16][4] = {
  447. ROP2(cirrus_colorexpand_0),
  448. ROP2(cirrus_colorexpand_src_and_dst),
  449. ROP_NOP2(cirrus_bitblt_rop_nop),
  450. ROP2(cirrus_colorexpand_src_and_notdst),
  451. ROP2(cirrus_colorexpand_notdst),
  452. ROP2(cirrus_colorexpand_src),
  453. ROP2(cirrus_colorexpand_1),
  454. ROP2(cirrus_colorexpand_notsrc_and_dst),
  455. ROP2(cirrus_colorexpand_src_xor_dst),
  456. ROP2(cirrus_colorexpand_src_or_dst),
  457. ROP2(cirrus_colorexpand_notsrc_or_notdst),
  458. ROP2(cirrus_colorexpand_src_notxor_dst),
  459. ROP2(cirrus_colorexpand_src_or_notdst),
  460. ROP2(cirrus_colorexpand_notsrc),
  461. ROP2(cirrus_colorexpand_notsrc_or_dst),
  462. ROP2(cirrus_colorexpand_notsrc_and_notdst),
  463. };
  464. static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern_transp[16][4] = {
  465. ROP2(cirrus_colorexpand_pattern_transp_0),
  466. ROP2(cirrus_colorexpand_pattern_transp_src_and_dst),
  467. ROP_NOP2(cirrus_bitblt_rop_nop),
  468. ROP2(cirrus_colorexpand_pattern_transp_src_and_notdst),
  469. ROP2(cirrus_colorexpand_pattern_transp_notdst),
  470. ROP2(cirrus_colorexpand_pattern_transp_src),
  471. ROP2(cirrus_colorexpand_pattern_transp_1),
  472. ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_dst),
  473. ROP2(cirrus_colorexpand_pattern_transp_src_xor_dst),
  474. ROP2(cirrus_colorexpand_pattern_transp_src_or_dst),
  475. ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_notdst),
  476. ROP2(cirrus_colorexpand_pattern_transp_src_notxor_dst),
  477. ROP2(cirrus_colorexpand_pattern_transp_src_or_notdst),
  478. ROP2(cirrus_colorexpand_pattern_transp_notsrc),
  479. ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_dst),
  480. ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_notdst),
  481. };
  482. static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern[16][4] = {
  483. ROP2(cirrus_colorexpand_pattern_0),
  484. ROP2(cirrus_colorexpand_pattern_src_and_dst),
  485. ROP_NOP2(cirrus_bitblt_rop_nop),
  486. ROP2(cirrus_colorexpand_pattern_src_and_notdst),
  487. ROP2(cirrus_colorexpand_pattern_notdst),
  488. ROP2(cirrus_colorexpand_pattern_src),
  489. ROP2(cirrus_colorexpand_pattern_1),
  490. ROP2(cirrus_colorexpand_pattern_notsrc_and_dst),
  491. ROP2(cirrus_colorexpand_pattern_src_xor_dst),
  492. ROP2(cirrus_colorexpand_pattern_src_or_dst),
  493. ROP2(cirrus_colorexpand_pattern_notsrc_or_notdst),
  494. ROP2(cirrus_colorexpand_pattern_src_notxor_dst),
  495. ROP2(cirrus_colorexpand_pattern_src_or_notdst),
  496. ROP2(cirrus_colorexpand_pattern_notsrc),
  497. ROP2(cirrus_colorexpand_pattern_notsrc_or_dst),
  498. ROP2(cirrus_colorexpand_pattern_notsrc_and_notdst),
  499. };
  500. static const cirrus_fill_t cirrus_fill[16][4] = {
  501. ROP2(cirrus_fill_0),
  502. ROP2(cirrus_fill_src_and_dst),
  503. ROP_NOP2(cirrus_bitblt_fill_nop),
  504. ROP2(cirrus_fill_src_and_notdst),
  505. ROP2(cirrus_fill_notdst),
  506. ROP2(cirrus_fill_src),
  507. ROP2(cirrus_fill_1),
  508. ROP2(cirrus_fill_notsrc_and_dst),
  509. ROP2(cirrus_fill_src_xor_dst),
  510. ROP2(cirrus_fill_src_or_dst),
  511. ROP2(cirrus_fill_notsrc_or_notdst),
  512. ROP2(cirrus_fill_src_notxor_dst),
  513. ROP2(cirrus_fill_src_or_notdst),
  514. ROP2(cirrus_fill_notsrc),
  515. ROP2(cirrus_fill_notsrc_or_dst),
  516. ROP2(cirrus_fill_notsrc_and_notdst),
  517. };
  518. static inline void cirrus_bitblt_fgcol(CirrusVGAState *s)
  519. {
  520. unsigned int color;
  521. switch (s->cirrus_blt_pixelwidth) {
  522. case 1:
  523. s->cirrus_blt_fgcol = s->cirrus_shadow_gr1;
  524. break;
  525. case 2:
  526. color = s->cirrus_shadow_gr1 | (s->vga.gr[0x11] << 8);
  527. s->cirrus_blt_fgcol = le16_to_cpu(color);
  528. break;
  529. case 3:
  530. s->cirrus_blt_fgcol = s->cirrus_shadow_gr1 |
  531. (s->vga.gr[0x11] << 8) | (s->vga.gr[0x13] << 16);
  532. break;
  533. default:
  534. case 4:
  535. color = s->cirrus_shadow_gr1 | (s->vga.gr[0x11] << 8) |
  536. (s->vga.gr[0x13] << 16) | (s->vga.gr[0x15] << 24);
  537. s->cirrus_blt_fgcol = le32_to_cpu(color);
  538. break;
  539. }
  540. }
  541. static inline void cirrus_bitblt_bgcol(CirrusVGAState *s)
  542. {
  543. unsigned int color;
  544. switch (s->cirrus_blt_pixelwidth) {
  545. case 1:
  546. s->cirrus_blt_bgcol = s->cirrus_shadow_gr0;
  547. break;
  548. case 2:
  549. color = s->cirrus_shadow_gr0 | (s->vga.gr[0x10] << 8);
  550. s->cirrus_blt_bgcol = le16_to_cpu(color);
  551. break;
  552. case 3:
  553. s->cirrus_blt_bgcol = s->cirrus_shadow_gr0 |
  554. (s->vga.gr[0x10] << 8) | (s->vga.gr[0x12] << 16);
  555. break;
  556. default:
  557. case 4:
  558. color = s->cirrus_shadow_gr0 | (s->vga.gr[0x10] << 8) |
  559. (s->vga.gr[0x12] << 16) | (s->vga.gr[0x14] << 24);
  560. s->cirrus_blt_bgcol = le32_to_cpu(color);
  561. break;
  562. }
  563. }
  564. static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
  565. int off_pitch, int bytesperline,
  566. int lines)
  567. {
  568. int y;
  569. int off_cur;
  570. int off_cur_end;
  571. if (off_pitch < 0) {
  572. off_begin -= bytesperline - 1;
  573. }
  574. for (y = 0; y < lines; y++) {
  575. off_cur = off_begin & s->cirrus_addr_mask;
  576. off_cur_end = ((off_cur + bytesperline - 1) & s->cirrus_addr_mask) + 1;
  577. if (off_cur_end >= off_cur) {
  578. memory_region_set_dirty(&s->vga.vram, off_cur, off_cur_end - off_cur);
  579. } else {
  580. /* wraparound */
  581. memory_region_set_dirty(&s->vga.vram, off_cur,
  582. s->cirrus_addr_mask + 1 - off_cur);
  583. memory_region_set_dirty(&s->vga.vram, 0, off_cur_end);
  584. }
  585. off_begin += off_pitch;
  586. }
  587. }
  588. static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s)
  589. {
  590. uint32_t patternsize;
  591. bool videosrc = !s->cirrus_srccounter;
  592. if (videosrc) {
  593. switch (s->vga.get_bpp(&s->vga)) {
  594. case 8:
  595. patternsize = 64;
  596. break;
  597. case 15:
  598. case 16:
  599. patternsize = 128;
  600. break;
  601. case 24:
  602. case 32:
  603. default:
  604. patternsize = 256;
  605. break;
  606. }
  607. s->cirrus_blt_srcaddr &= ~(patternsize - 1);
  608. if (s->cirrus_blt_srcaddr + patternsize > s->vga.vram_size) {
  609. return 0;
  610. }
  611. }
  612. if (blit_is_unsafe(s, true)) {
  613. return 0;
  614. }
  615. (*s->cirrus_rop) (s, s->cirrus_blt_dstaddr,
  616. videosrc ? s->cirrus_blt_srcaddr : 0,
  617. s->cirrus_blt_dstpitch, 0,
  618. s->cirrus_blt_width, s->cirrus_blt_height);
  619. cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
  620. s->cirrus_blt_dstpitch, s->cirrus_blt_width,
  621. s->cirrus_blt_height);
  622. return 1;
  623. }
  624. /* fill */
  625. static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
  626. {
  627. cirrus_fill_t rop_func;
  628. if (blit_is_unsafe(s, true)) {
  629. return 0;
  630. }
  631. rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
  632. rop_func(s, s->cirrus_blt_dstaddr,
  633. s->cirrus_blt_dstpitch,
  634. s->cirrus_blt_width, s->cirrus_blt_height);
  635. cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
  636. s->cirrus_blt_dstpitch, s->cirrus_blt_width,
  637. s->cirrus_blt_height);
  638. cirrus_bitblt_reset(s);
  639. return 1;
  640. }
  641. /***************************************
  642. *
  643. * bitblt (video-to-video)
  644. *
  645. ***************************************/
  646. static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
  647. {
  648. return cirrus_bitblt_common_patterncopy(s);
  649. }
  650. static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
  651. {
  652. int sx = 0, sy = 0;
  653. int dx = 0, dy = 0;
  654. int depth = 0;
  655. int notify = 0;
  656. /* make sure to only copy if it's a plain copy ROP */
  657. if (*s->cirrus_rop == cirrus_bitblt_rop_fwd_src ||
  658. *s->cirrus_rop == cirrus_bitblt_rop_bkwd_src) {
  659. int width, height;
  660. depth = s->vga.get_bpp(&s->vga) / 8;
  661. if (!depth) {
  662. return 0;
  663. }
  664. s->vga.get_resolution(&s->vga, &width, &height);
  665. /* extra x, y */
  666. sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
  667. sy = (src / ABS(s->cirrus_blt_srcpitch));
  668. dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth;
  669. dy = (dst / ABS(s->cirrus_blt_dstpitch));
  670. /* normalize width */
  671. w /= depth;
  672. /* if we're doing a backward copy, we have to adjust
  673. our x/y to be the upper left corner (instead of the lower
  674. right corner) */
  675. if (s->cirrus_blt_dstpitch < 0) {
  676. sx -= (s->cirrus_blt_width / depth) - 1;
  677. dx -= (s->cirrus_blt_width / depth) - 1;
  678. sy -= s->cirrus_blt_height - 1;
  679. dy -= s->cirrus_blt_height - 1;
  680. }
  681. /* are we in the visible portion of memory? */
  682. if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 &&
  683. (sx + w) <= width && (sy + h) <= height &&
  684. (dx + w) <= width && (dy + h) <= height) {
  685. notify = 1;
  686. }
  687. }
  688. (*s->cirrus_rop) (s, s->cirrus_blt_dstaddr,
  689. s->cirrus_blt_srcaddr,
  690. s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
  691. s->cirrus_blt_width, s->cirrus_blt_height);
  692. if (notify) {
  693. dpy_gfx_update(s->vga.con, dx, dy,
  694. s->cirrus_blt_width / depth,
  695. s->cirrus_blt_height);
  696. }
  697. /* we don't have to notify the display that this portion has
  698. changed since qemu_console_copy implies this */
  699. cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
  700. s->cirrus_blt_dstpitch, s->cirrus_blt_width,
  701. s->cirrus_blt_height);
  702. return 1;
  703. }
  704. static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
  705. {
  706. if (blit_is_unsafe(s, false))
  707. return 0;
  708. return cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr,
  709. s->cirrus_blt_srcaddr - s->vga.start_addr,
  710. s->cirrus_blt_width, s->cirrus_blt_height);
  711. }
  712. /***************************************
  713. *
  714. * bitblt (cpu-to-video)
  715. *
  716. ***************************************/
  717. static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s)
  718. {
  719. int copy_count;
  720. uint8_t *end_ptr;
  721. if (s->cirrus_srccounter > 0) {
  722. if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
  723. cirrus_bitblt_common_patterncopy(s);
  724. the_end:
  725. s->cirrus_srccounter = 0;
  726. cirrus_bitblt_reset(s);
  727. } else {
  728. /* at least one scan line */
  729. do {
  730. (*s->cirrus_rop)(s, s->cirrus_blt_dstaddr,
  731. 0, 0, 0, s->cirrus_blt_width, 1);
  732. cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
  733. s->cirrus_blt_width, 1);
  734. s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch;
  735. s->cirrus_srccounter -= s->cirrus_blt_srcpitch;
  736. if (s->cirrus_srccounter <= 0)
  737. goto the_end;
  738. /* more bytes than needed can be transferred because of
  739. word alignment, so we keep them for the next line */
  740. /* XXX: keep alignment to speed up transfer */
  741. end_ptr = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
  742. copy_count = MIN(s->cirrus_srcptr_end - end_ptr, CIRRUS_BLTBUFSIZE);
  743. memmove(s->cirrus_bltbuf, end_ptr, copy_count);
  744. s->cirrus_srcptr = s->cirrus_bltbuf + copy_count;
  745. s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
  746. } while (s->cirrus_srcptr >= s->cirrus_srcptr_end);
  747. }
  748. }
  749. }
  750. /***************************************
  751. *
  752. * bitblt wrapper
  753. *
  754. ***************************************/
  755. static void cirrus_bitblt_reset(CirrusVGAState * s)
  756. {
  757. int need_update;
  758. s->vga.gr[0x31] &=
  759. ~(CIRRUS_BLT_START | CIRRUS_BLT_BUSY | CIRRUS_BLT_FIFOUSED);
  760. need_update = s->cirrus_srcptr != &s->cirrus_bltbuf[0]
  761. || s->cirrus_srcptr_end != &s->cirrus_bltbuf[0];
  762. s->cirrus_srcptr = &s->cirrus_bltbuf[0];
  763. s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
  764. s->cirrus_srccounter = 0;
  765. if (!need_update)
  766. return;
  767. cirrus_update_memory_access(s);
  768. }
  769. static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
  770. {
  771. int w;
  772. if (blit_is_unsafe(s, true)) {
  773. return 0;
  774. }
  775. s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC;
  776. s->cirrus_srcptr = &s->cirrus_bltbuf[0];
  777. s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
  778. if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
  779. if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
  780. s->cirrus_blt_srcpitch = 8;
  781. } else {
  782. /* XXX: check for 24 bpp */
  783. s->cirrus_blt_srcpitch = 8 * 8 * s->cirrus_blt_pixelwidth;
  784. }
  785. s->cirrus_srccounter = s->cirrus_blt_srcpitch;
  786. } else {
  787. if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
  788. w = s->cirrus_blt_width / s->cirrus_blt_pixelwidth;
  789. if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)
  790. s->cirrus_blt_srcpitch = ((w + 31) >> 5);
  791. else
  792. s->cirrus_blt_srcpitch = ((w + 7) >> 3);
  793. } else {
  794. /* always align input size to 32 bits */
  795. s->cirrus_blt_srcpitch = (s->cirrus_blt_width + 3) & ~3;
  796. }
  797. s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height;
  798. }
  799. /* the blit_is_unsafe call above should catch this */
  800. assert(s->cirrus_blt_srcpitch <= CIRRUS_BLTBUFSIZE);
  801. s->cirrus_srcptr = s->cirrus_bltbuf;
  802. s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
  803. cirrus_update_memory_access(s);
  804. return 1;
  805. }
  806. static int cirrus_bitblt_videotocpu(CirrusVGAState * s)
  807. {
  808. /* XXX */
  809. qemu_log_mask(LOG_UNIMP,
  810. "cirrus: bitblt (video to cpu) is not implemented\n");
  811. return 0;
  812. }
  813. static int cirrus_bitblt_videotovideo(CirrusVGAState * s)
  814. {
  815. int ret;
  816. if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
  817. ret = cirrus_bitblt_videotovideo_patterncopy(s);
  818. } else {
  819. ret = cirrus_bitblt_videotovideo_copy(s);
  820. }
  821. if (ret)
  822. cirrus_bitblt_reset(s);
  823. return ret;
  824. }
  825. static void cirrus_bitblt_start(CirrusVGAState * s)
  826. {
  827. uint8_t blt_rop;
  828. if (!s->enable_blitter) {
  829. goto bitblt_ignore;
  830. }
  831. s->vga.gr[0x31] |= CIRRUS_BLT_BUSY;
  832. s->cirrus_blt_width = (s->vga.gr[0x20] | (s->vga.gr[0x21] << 8)) + 1;
  833. s->cirrus_blt_height = (s->vga.gr[0x22] | (s->vga.gr[0x23] << 8)) + 1;
  834. s->cirrus_blt_dstpitch = (s->vga.gr[0x24] | (s->vga.gr[0x25] << 8));
  835. s->cirrus_blt_srcpitch = (s->vga.gr[0x26] | (s->vga.gr[0x27] << 8));
  836. s->cirrus_blt_dstaddr =
  837. (s->vga.gr[0x28] | (s->vga.gr[0x29] << 8) | (s->vga.gr[0x2a] << 16));
  838. s->cirrus_blt_srcaddr =
  839. (s->vga.gr[0x2c] | (s->vga.gr[0x2d] << 8) | (s->vga.gr[0x2e] << 16));
  840. s->cirrus_blt_mode = s->vga.gr[0x30];
  841. s->cirrus_blt_modeext = s->vga.gr[0x33];
  842. blt_rop = s->vga.gr[0x32];
  843. s->cirrus_blt_dstaddr &= s->cirrus_addr_mask;
  844. s->cirrus_blt_srcaddr &= s->cirrus_addr_mask;
  845. trace_vga_cirrus_bitblt_start(blt_rop,
  846. s->cirrus_blt_mode,
  847. s->cirrus_blt_modeext,
  848. s->cirrus_blt_width,
  849. s->cirrus_blt_height,
  850. s->cirrus_blt_dstpitch,
  851. s->cirrus_blt_srcpitch,
  852. s->cirrus_blt_dstaddr,
  853. s->cirrus_blt_srcaddr,
  854. s->vga.gr[0x2f]);
  855. switch (s->cirrus_blt_mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) {
  856. case CIRRUS_BLTMODE_PIXELWIDTH8:
  857. s->cirrus_blt_pixelwidth = 1;
  858. break;
  859. case CIRRUS_BLTMODE_PIXELWIDTH16:
  860. s->cirrus_blt_pixelwidth = 2;
  861. break;
  862. case CIRRUS_BLTMODE_PIXELWIDTH24:
  863. s->cirrus_blt_pixelwidth = 3;
  864. break;
  865. case CIRRUS_BLTMODE_PIXELWIDTH32:
  866. s->cirrus_blt_pixelwidth = 4;
  867. break;
  868. default:
  869. qemu_log_mask(LOG_GUEST_ERROR,
  870. "cirrus: bitblt - pixel width is unknown\n");
  871. goto bitblt_ignore;
  872. }
  873. s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_PIXELWIDTHMASK;
  874. if ((s->
  875. cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSSRC |
  876. CIRRUS_BLTMODE_MEMSYSDEST))
  877. == (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) {
  878. qemu_log_mask(LOG_UNIMP,
  879. "cirrus: bitblt - memory-to-memory copy requested\n");
  880. goto bitblt_ignore;
  881. }
  882. if ((s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) &&
  883. (s->cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSDEST |
  884. CIRRUS_BLTMODE_TRANSPARENTCOMP |
  885. CIRRUS_BLTMODE_PATTERNCOPY |
  886. CIRRUS_BLTMODE_COLOREXPAND)) ==
  887. (CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) {
  888. cirrus_bitblt_fgcol(s);
  889. cirrus_bitblt_solidfill(s, blt_rop);
  890. } else {
  891. if ((s->cirrus_blt_mode & (CIRRUS_BLTMODE_COLOREXPAND |
  892. CIRRUS_BLTMODE_PATTERNCOPY)) ==
  893. CIRRUS_BLTMODE_COLOREXPAND) {
  894. if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
  895. if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)
  896. cirrus_bitblt_bgcol(s);
  897. else
  898. cirrus_bitblt_fgcol(s);
  899. s->cirrus_rop = cirrus_colorexpand_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
  900. } else {
  901. cirrus_bitblt_fgcol(s);
  902. cirrus_bitblt_bgcol(s);
  903. s->cirrus_rop = cirrus_colorexpand[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
  904. }
  905. } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
  906. if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
  907. if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
  908. if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)
  909. cirrus_bitblt_bgcol(s);
  910. else
  911. cirrus_bitblt_fgcol(s);
  912. s->cirrus_rop = cirrus_colorexpand_pattern_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
  913. } else {
  914. cirrus_bitblt_fgcol(s);
  915. cirrus_bitblt_bgcol(s);
  916. s->cirrus_rop = cirrus_colorexpand_pattern[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
  917. }
  918. } else {
  919. s->cirrus_rop = cirrus_patternfill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
  920. }
  921. } else {
  922. if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
  923. if (s->cirrus_blt_pixelwidth > 2) {
  924. qemu_log_mask(LOG_GUEST_ERROR,
  925. "cirrus: src transparent without colorexpand "
  926. "must be 8bpp or 16bpp\n");
  927. goto bitblt_ignore;
  928. }
  929. if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {
  930. s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;
  931. s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;
  932. s->cirrus_rop = cirrus_bkwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
  933. } else {
  934. s->cirrus_rop = cirrus_fwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
  935. }
  936. } else {
  937. if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {
  938. s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;
  939. s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;
  940. s->cirrus_rop = cirrus_bkwd_rop[rop_to_index[blt_rop]];
  941. } else {
  942. s->cirrus_rop = cirrus_fwd_rop[rop_to_index[blt_rop]];
  943. }
  944. }
  945. }
  946. // setup bitblt engine.
  947. if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSSRC) {
  948. if (!cirrus_bitblt_cputovideo(s))
  949. goto bitblt_ignore;
  950. } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSDEST) {
  951. if (!cirrus_bitblt_videotocpu(s))
  952. goto bitblt_ignore;
  953. } else {
  954. if (!cirrus_bitblt_videotovideo(s))
  955. goto bitblt_ignore;
  956. }
  957. }
  958. return;
  959. bitblt_ignore:;
  960. cirrus_bitblt_reset(s);
  961. }
  962. static void cirrus_write_bitblt(CirrusVGAState * s, unsigned reg_value)
  963. {
  964. unsigned old_value;
  965. old_value = s->vga.gr[0x31];
  966. s->vga.gr[0x31] = reg_value;
  967. if (((old_value & CIRRUS_BLT_RESET) != 0) &&
  968. ((reg_value & CIRRUS_BLT_RESET) == 0)) {
  969. cirrus_bitblt_reset(s);
  970. } else if (((old_value & CIRRUS_BLT_START) == 0) &&
  971. ((reg_value & CIRRUS_BLT_START) != 0)) {
  972. cirrus_bitblt_start(s);
  973. }
  974. }
  975. /***************************************
  976. *
  977. * basic parameters
  978. *
  979. ***************************************/
  980. static void cirrus_get_offsets(VGACommonState *s1,
  981. uint32_t *pline_offset,
  982. uint32_t *pstart_addr,
  983. uint32_t *pline_compare)
  984. {
  985. CirrusVGAState * s = container_of(s1, CirrusVGAState, vga);
  986. uint32_t start_addr, line_offset, line_compare;
  987. line_offset = s->vga.cr[0x13]
  988. | ((s->vga.cr[0x1b] & 0x10) << 4);
  989. line_offset <<= 3;
  990. *pline_offset = line_offset;
  991. start_addr = (s->vga.cr[0x0c] << 8)
  992. | s->vga.cr[0x0d]
  993. | ((s->vga.cr[0x1b] & 0x01) << 16)
  994. | ((s->vga.cr[0x1b] & 0x0c) << 15)
  995. | ((s->vga.cr[0x1d] & 0x80) << 12);
  996. *pstart_addr = start_addr;
  997. line_compare = s->vga.cr[0x18] |
  998. ((s->vga.cr[0x07] & 0x10) << 4) |
  999. ((s->vga.cr[0x09] & 0x40) << 3);
  1000. *pline_compare = line_compare;
  1001. }
  1002. static uint32_t cirrus_get_bpp16_depth(CirrusVGAState * s)
  1003. {
  1004. uint32_t ret = 16;
  1005. switch (s->cirrus_hidden_dac_data & 0xf) {
  1006. case 0:
  1007. ret = 15;
  1008. break; /* Sierra HiColor */
  1009. case 1:
  1010. ret = 16;
  1011. break; /* XGA HiColor */
  1012. default:
  1013. qemu_log_mask(LOG_GUEST_ERROR,
  1014. "cirrus: invalid DAC value 0x%x in 16bpp\n",
  1015. (s->cirrus_hidden_dac_data & 0xf));
  1016. ret = 15; /* XXX */
  1017. break;
  1018. }
  1019. return ret;
  1020. }
  1021. static int cirrus_get_bpp(VGACommonState *s1)
  1022. {
  1023. CirrusVGAState * s = container_of(s1, CirrusVGAState, vga);
  1024. uint32_t ret = 8;
  1025. if ((s->vga.sr[0x07] & 0x01) != 0) {
  1026. /* Cirrus SVGA */
  1027. switch (s->vga.sr[0x07] & CIRRUS_SR7_BPP_MASK) {
  1028. case CIRRUS_SR7_BPP_8:
  1029. ret = 8;
  1030. break;
  1031. case CIRRUS_SR7_BPP_16_DOUBLEVCLK:
  1032. ret = cirrus_get_bpp16_depth(s);
  1033. break;
  1034. case CIRRUS_SR7_BPP_24:
  1035. ret = 24;
  1036. break;
  1037. case CIRRUS_SR7_BPP_16:
  1038. ret = cirrus_get_bpp16_depth(s);
  1039. break;
  1040. case CIRRUS_SR7_BPP_32:
  1041. ret = 32;
  1042. break;
  1043. default:
  1044. #ifdef DEBUG_CIRRUS
  1045. printf("cirrus: unknown bpp - sr7=%x\n", s->vga.sr[0x7]);
  1046. #endif
  1047. ret = 8;
  1048. break;
  1049. }
  1050. } else {
  1051. /* VGA */
  1052. ret = 0;
  1053. }
  1054. return ret;
  1055. }
  1056. static void cirrus_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
  1057. {
  1058. int width, height;
  1059. width = (s->cr[0x01] + 1) * 8;
  1060. height = s->cr[0x12] |
  1061. ((s->cr[0x07] & 0x02) << 7) |
  1062. ((s->cr[0x07] & 0x40) << 3);
  1063. height = (height + 1);
  1064. /* interlace support */
  1065. if (s->cr[0x1a] & 0x01)
  1066. height = height * 2;
  1067. *pwidth = width;
  1068. *pheight = height;
  1069. }
  1070. /***************************************
  1071. *
  1072. * bank memory
  1073. *
  1074. ***************************************/
  1075. static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index)
  1076. {
  1077. unsigned offset;
  1078. unsigned limit;
  1079. if ((s->vga.gr[0x0b] & 0x01) != 0) /* dual bank */
  1080. offset = s->vga.gr[0x09 + bank_index];
  1081. else /* single bank */
  1082. offset = s->vga.gr[0x09];
  1083. if ((s->vga.gr[0x0b] & 0x20) != 0)
  1084. offset <<= 14;
  1085. else
  1086. offset <<= 12;
  1087. if (s->real_vram_size <= offset)
  1088. limit = 0;
  1089. else
  1090. limit = s->real_vram_size - offset;
  1091. if (((s->vga.gr[0x0b] & 0x01) == 0) && (bank_index != 0)) {
  1092. if (limit > 0x8000) {
  1093. offset += 0x8000;
  1094. limit -= 0x8000;
  1095. } else {
  1096. limit = 0;
  1097. }
  1098. }
  1099. if (limit > 0) {
  1100. s->cirrus_bank_base[bank_index] = offset;
  1101. s->cirrus_bank_limit[bank_index] = limit;
  1102. } else {
  1103. s->cirrus_bank_base[bank_index] = 0;
  1104. s->cirrus_bank_limit[bank_index] = 0;
  1105. }
  1106. }
  1107. /***************************************
  1108. *
  1109. * I/O access between 0x3c4-0x3c5
  1110. *
  1111. ***************************************/
  1112. static int cirrus_vga_read_sr(CirrusVGAState * s)
  1113. {
  1114. switch (s->vga.sr_index) {
  1115. case 0x00: // Standard VGA
  1116. case 0x01: // Standard VGA
  1117. case 0x02: // Standard VGA
  1118. case 0x03: // Standard VGA
  1119. case 0x04: // Standard VGA
  1120. return s->vga.sr[s->vga.sr_index];
  1121. case 0x06: // Unlock Cirrus extensions
  1122. return s->vga.sr[s->vga.sr_index];
  1123. case 0x10:
  1124. case 0x30:
  1125. case 0x50:
  1126. case 0x70: // Graphics Cursor X
  1127. case 0x90:
  1128. case 0xb0:
  1129. case 0xd0:
  1130. case 0xf0: // Graphics Cursor X
  1131. return s->vga.sr[0x10];
  1132. case 0x11:
  1133. case 0x31:
  1134. case 0x51:
  1135. case 0x71: // Graphics Cursor Y
  1136. case 0x91:
  1137. case 0xb1:
  1138. case 0xd1:
  1139. case 0xf1: // Graphics Cursor Y
  1140. return s->vga.sr[0x11];
  1141. case 0x05: // ???
  1142. case 0x07: // Extended Sequencer Mode
  1143. case 0x08: // EEPROM Control
  1144. case 0x09: // Scratch Register 0
  1145. case 0x0a: // Scratch Register 1
  1146. case 0x0b: // VCLK 0
  1147. case 0x0c: // VCLK 1
  1148. case 0x0d: // VCLK 2
  1149. case 0x0e: // VCLK 3
  1150. case 0x0f: // DRAM Control
  1151. case 0x12: // Graphics Cursor Attribute
  1152. case 0x13: // Graphics Cursor Pattern Address
  1153. case 0x14: // Scratch Register 2
  1154. case 0x15: // Scratch Register 3
  1155. case 0x16: // Performance Tuning Register
  1156. case 0x17: // Configuration Readback and Extended Control
  1157. case 0x18: // Signature Generator Control
  1158. case 0x19: // Signal Generator Result
  1159. case 0x1a: // Signal Generator Result
  1160. case 0x1b: // VCLK 0 Denominator & Post
  1161. case 0x1c: // VCLK 1 Denominator & Post
  1162. case 0x1d: // VCLK 2 Denominator & Post
  1163. case 0x1e: // VCLK 3 Denominator & Post
  1164. case 0x1f: // BIOS Write Enable and MCLK select
  1165. #ifdef DEBUG_CIRRUS
  1166. printf("cirrus: handled inport sr_index %02x\n", s->vga.sr_index);
  1167. #endif
  1168. return s->vga.sr[s->vga.sr_index];
  1169. default:
  1170. qemu_log_mask(LOG_GUEST_ERROR,
  1171. "cirrus: inport sr_index 0x%02x\n", s->vga.sr_index);
  1172. return 0xff;
  1173. }
  1174. }
  1175. static void cirrus_vga_write_sr(CirrusVGAState * s, uint32_t val)
  1176. {
  1177. switch (s->vga.sr_index) {
  1178. case 0x00: // Standard VGA
  1179. case 0x01: // Standard VGA
  1180. case 0x02: // Standard VGA
  1181. case 0x03: // Standard VGA
  1182. case 0x04: // Standard VGA
  1183. s->vga.sr[s->vga.sr_index] = val & sr_mask[s->vga.sr_index];
  1184. if (s->vga.sr_index == 1)
  1185. s->vga.update_retrace_info(&s->vga);
  1186. break;
  1187. case 0x06: // Unlock Cirrus extensions
  1188. val &= 0x17;
  1189. if (val == 0x12) {
  1190. s->vga.sr[s->vga.sr_index] = 0x12;
  1191. } else {
  1192. s->vga.sr[s->vga.sr_index] = 0x0f;
  1193. }
  1194. break;
  1195. case 0x10:
  1196. case 0x30:
  1197. case 0x50:
  1198. case 0x70: // Graphics Cursor X
  1199. case 0x90:
  1200. case 0xb0:
  1201. case 0xd0:
  1202. case 0xf0: // Graphics Cursor X
  1203. s->vga.sr[0x10] = val;
  1204. s->vga.hw_cursor_x = (val << 3) | (s->vga.sr_index >> 5);
  1205. break;
  1206. case 0x11:
  1207. case 0x31:
  1208. case 0x51:
  1209. case 0x71: // Graphics Cursor Y
  1210. case 0x91:
  1211. case 0xb1:
  1212. case 0xd1:
  1213. case 0xf1: // Graphics Cursor Y
  1214. s->vga.sr[0x11] = val;
  1215. s->vga.hw_cursor_y = (val << 3) | (s->vga.sr_index >> 5);
  1216. break;
  1217. case 0x07: // Extended Sequencer Mode
  1218. cirrus_update_memory_access(s);
  1219. /* fall through */
  1220. case 0x08: // EEPROM Control
  1221. case 0x09: // Scratch Register 0
  1222. case 0x0a: // Scratch Register 1
  1223. case 0x0b: // VCLK 0
  1224. case 0x0c: // VCLK 1
  1225. case 0x0d: // VCLK 2
  1226. case 0x0e: // VCLK 3
  1227. case 0x0f: // DRAM Control
  1228. case 0x13: // Graphics Cursor Pattern Address
  1229. case 0x14: // Scratch Register 2
  1230. case 0x15: // Scratch Register 3
  1231. case 0x16: // Performance Tuning Register
  1232. case 0x18: // Signature Generator Control
  1233. case 0x19: // Signature Generator Result
  1234. case 0x1a: // Signature Generator Result
  1235. case 0x1b: // VCLK 0 Denominator & Post
  1236. case 0x1c: // VCLK 1 Denominator & Post
  1237. case 0x1d: // VCLK 2 Denominator & Post
  1238. case 0x1e: // VCLK 3 Denominator & Post
  1239. case 0x1f: // BIOS Write Enable and MCLK select
  1240. s->vga.sr[s->vga.sr_index] = val;
  1241. #ifdef DEBUG_CIRRUS
  1242. printf("cirrus: handled outport sr_index %02x, sr_value %02x\n",
  1243. s->vga.sr_index, val);
  1244. #endif
  1245. break;
  1246. case 0x12: // Graphics Cursor Attribute
  1247. s->vga.sr[0x12] = val;
  1248. s->vga.force_shadow = !!(val & CIRRUS_CURSOR_SHOW);
  1249. #ifdef DEBUG_CIRRUS
  1250. printf("cirrus: cursor ctl SR12=%02x (force shadow: %d)\n",
  1251. val, s->vga.force_shadow);
  1252. #endif
  1253. break;
  1254. case 0x17: // Configuration Readback and Extended Control
  1255. s->vga.sr[s->vga.sr_index] = (s->vga.sr[s->vga.sr_index] & 0x38)
  1256. | (val & 0xc7);
  1257. cirrus_update_memory_access(s);
  1258. break;
  1259. default:
  1260. qemu_log_mask(LOG_GUEST_ERROR,
  1261. "cirrus: outport sr_index 0x%02x, sr_value 0x%02x\n",
  1262. s->vga.sr_index, val);
  1263. break;
  1264. }
  1265. }
  1266. /***************************************
  1267. *
  1268. * I/O access at 0x3c6
  1269. *
  1270. ***************************************/
  1271. static int cirrus_read_hidden_dac(CirrusVGAState * s)
  1272. {
  1273. if (++s->cirrus_hidden_dac_lockindex == 5) {
  1274. s->cirrus_hidden_dac_lockindex = 0;
  1275. return s->cirrus_hidden_dac_data;
  1276. }
  1277. return 0xff;
  1278. }
  1279. static void cirrus_write_hidden_dac(CirrusVGAState * s, int reg_value)
  1280. {
  1281. if (s->cirrus_hidden_dac_lockindex == 4) {
  1282. s->cirrus_hidden_dac_data = reg_value;
  1283. #if defined(DEBUG_CIRRUS)
  1284. printf("cirrus: outport hidden DAC, value %02x\n", reg_value);
  1285. #endif
  1286. }
  1287. s->cirrus_hidden_dac_lockindex = 0;
  1288. }
  1289. /***************************************
  1290. *
  1291. * I/O access at 0x3c9
  1292. *
  1293. ***************************************/
  1294. static int cirrus_vga_read_palette(CirrusVGAState * s)
  1295. {
  1296. int val;
  1297. if ((s->vga.sr[0x12] & CIRRUS_CURSOR_HIDDENPEL)) {
  1298. val = s->cirrus_hidden_palette[(s->vga.dac_read_index & 0x0f) * 3 +
  1299. s->vga.dac_sub_index];
  1300. } else {
  1301. val = s->vga.palette[s->vga.dac_read_index * 3 + s->vga.dac_sub_index];
  1302. }
  1303. if (++s->vga.dac_sub_index == 3) {
  1304. s->vga.dac_sub_index = 0;
  1305. s->vga.dac_read_index++;
  1306. }
  1307. return val;
  1308. }
  1309. static void cirrus_vga_write_palette(CirrusVGAState * s, int reg_value)
  1310. {
  1311. s->vga.dac_cache[s->vga.dac_sub_index] = reg_value;
  1312. if (++s->vga.dac_sub_index == 3) {
  1313. if ((s->vga.sr[0x12] & CIRRUS_CURSOR_HIDDENPEL)) {
  1314. memcpy(&s->cirrus_hidden_palette[(s->vga.dac_write_index & 0x0f) * 3],
  1315. s->vga.dac_cache, 3);
  1316. } else {
  1317. memcpy(&s->vga.palette[s->vga.dac_write_index * 3], s->vga.dac_cache, 3);
  1318. }
  1319. /* XXX update cursor */
  1320. s->vga.dac_sub_index = 0;
  1321. s->vga.dac_write_index++;
  1322. }
  1323. }
  1324. /***************************************
  1325. *
  1326. * I/O access between 0x3ce-0x3cf
  1327. *
  1328. ***************************************/
  1329. static int cirrus_vga_read_gr(CirrusVGAState * s, unsigned reg_index)
  1330. {
  1331. switch (reg_index) {
  1332. case 0x00: // Standard VGA, BGCOLOR 0x000000ff
  1333. return s->cirrus_shadow_gr0;
  1334. case 0x01: // Standard VGA, FGCOLOR 0x000000ff
  1335. return s->cirrus_shadow_gr1;
  1336. case 0x02: // Standard VGA
  1337. case 0x03: // Standard VGA
  1338. case 0x04: // Standard VGA
  1339. case 0x06: // Standard VGA
  1340. case 0x07: // Standard VGA
  1341. case 0x08: // Standard VGA
  1342. return s->vga.gr[s->vga.gr_index];
  1343. case 0x05: // Standard VGA, Cirrus extended mode
  1344. default:
  1345. break;
  1346. }
  1347. if (reg_index < 0x3a) {
  1348. return s->vga.gr[reg_index];
  1349. } else {
  1350. qemu_log_mask(LOG_GUEST_ERROR,
  1351. "cirrus: inport gr_index 0x%02x\n", reg_index);
  1352. return 0xff;
  1353. }
  1354. }
  1355. static void
  1356. cirrus_vga_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value)
  1357. {
  1358. trace_vga_cirrus_write_gr(reg_index, reg_value);
  1359. switch (reg_index) {
  1360. case 0x00: // Standard VGA, BGCOLOR 0x000000ff
  1361. s->vga.gr[reg_index] = reg_value & gr_mask[reg_index];
  1362. s->cirrus_shadow_gr0 = reg_value;
  1363. break;
  1364. case 0x01: // Standard VGA, FGCOLOR 0x000000ff
  1365. s->vga.gr[reg_index] = reg_value & gr_mask[reg_index];
  1366. s->cirrus_shadow_gr1 = reg_value;
  1367. break;
  1368. case 0x02: // Standard VGA
  1369. case 0x03: // Standard VGA
  1370. case 0x04: // Standard VGA
  1371. case 0x06: // Standard VGA
  1372. case 0x07: // Standard VGA
  1373. case 0x08: // Standard VGA
  1374. s->vga.gr[reg_index] = reg_value & gr_mask[reg_index];
  1375. break;
  1376. case 0x05: // Standard VGA, Cirrus extended mode
  1377. s->vga.gr[reg_index] = reg_value & 0x7f;
  1378. cirrus_update_memory_access(s);
  1379. break;
  1380. case 0x09: // bank offset #0
  1381. case 0x0A: // bank offset #1
  1382. s->vga.gr[reg_index] = reg_value;
  1383. cirrus_update_bank_ptr(s, 0);
  1384. cirrus_update_bank_ptr(s, 1);
  1385. cirrus_update_memory_access(s);
  1386. break;
  1387. case 0x0B:
  1388. s->vga.gr[reg_index] = reg_value;
  1389. cirrus_update_bank_ptr(s, 0);
  1390. cirrus_update_bank_ptr(s, 1);
  1391. cirrus_update_memory_access(s);
  1392. break;
  1393. case 0x10: // BGCOLOR 0x0000ff00
  1394. case 0x11: // FGCOLOR 0x0000ff00
  1395. case 0x12: // BGCOLOR 0x00ff0000
  1396. case 0x13: // FGCOLOR 0x00ff0000
  1397. case 0x14: // BGCOLOR 0xff000000
  1398. case 0x15: // FGCOLOR 0xff000000
  1399. case 0x20: // BLT WIDTH 0x0000ff
  1400. case 0x22: // BLT HEIGHT 0x0000ff
  1401. case 0x24: // BLT DEST PITCH 0x0000ff
  1402. case 0x26: // BLT SRC PITCH 0x0000ff
  1403. case 0x28: // BLT DEST ADDR 0x0000ff
  1404. case 0x29: // BLT DEST ADDR 0x00ff00
  1405. case 0x2c: // BLT SRC ADDR 0x0000ff
  1406. case 0x2d: // BLT SRC ADDR 0x00ff00
  1407. case 0x2f: // BLT WRITEMASK
  1408. case 0x30: // BLT MODE
  1409. case 0x32: // RASTER OP
  1410. case 0x33: // BLT MODEEXT
  1411. case 0x34: // BLT TRANSPARENT COLOR 0x00ff
  1412. case 0x35: // BLT TRANSPARENT COLOR 0xff00
  1413. case 0x38: // BLT TRANSPARENT COLOR MASK 0x00ff
  1414. case 0x39: // BLT TRANSPARENT COLOR MASK 0xff00
  1415. s->vga.gr[reg_index] = reg_value;
  1416. break;
  1417. case 0x21: // BLT WIDTH 0x001f00
  1418. case 0x23: // BLT HEIGHT 0x001f00
  1419. case 0x25: // BLT DEST PITCH 0x001f00
  1420. case 0x27: // BLT SRC PITCH 0x001f00
  1421. s->vga.gr[reg_index] = reg_value & 0x1f;
  1422. break;
  1423. case 0x2a: // BLT DEST ADDR 0x3f0000
  1424. s->vga.gr[reg_index] = reg_value & 0x3f;
  1425. /* if auto start mode, starts bit blt now */
  1426. if (s->vga.gr[0x31] & CIRRUS_BLT_AUTOSTART) {
  1427. cirrus_bitblt_start(s);
  1428. }
  1429. break;
  1430. case 0x2e: // BLT SRC ADDR 0x3f0000
  1431. s->vga.gr[reg_index] = reg_value & 0x3f;
  1432. break;
  1433. case 0x31: // BLT STATUS/START
  1434. cirrus_write_bitblt(s, reg_value);
  1435. break;
  1436. default:
  1437. qemu_log_mask(LOG_GUEST_ERROR,
  1438. "cirrus: outport gr_index 0x%02x, gr_value 0x%02x\n",
  1439. reg_index, reg_value);
  1440. break;
  1441. }
  1442. }
  1443. /***************************************
  1444. *
  1445. * I/O access between 0x3d4-0x3d5
  1446. *
  1447. ***************************************/
  1448. static int cirrus_vga_read_cr(CirrusVGAState * s, unsigned reg_index)
  1449. {
  1450. switch (reg_index) {
  1451. case 0x00: // Standard VGA
  1452. case 0x01: // Standard VGA
  1453. case 0x02: // Standard VGA
  1454. case 0x03: // Standard VGA
  1455. case 0x04: // Standard VGA
  1456. case 0x05: // Standard VGA
  1457. case 0x06: // Standard VGA
  1458. case 0x07: // Standard VGA
  1459. case 0x08: // Standard VGA
  1460. case 0x09: // Standard VGA
  1461. case 0x0a: // Standard VGA
  1462. case 0x0b: // Standard VGA
  1463. case 0x0c: // Standard VGA
  1464. case 0x0d: // Standard VGA
  1465. case 0x0e: // Standard VGA
  1466. case 0x0f: // Standard VGA
  1467. case 0x10: // Standard VGA
  1468. case 0x11: // Standard VGA
  1469. case 0x12: // Standard VGA
  1470. case 0x13: // Standard VGA
  1471. case 0x14: // Standard VGA
  1472. case 0x15: // Standard VGA
  1473. case 0x16: // Standard VGA
  1474. case 0x17: // Standard VGA
  1475. case 0x18: // Standard VGA
  1476. return s->vga.cr[s->vga.cr_index];
  1477. case 0x24: // Attribute Controller Toggle Readback (R)
  1478. return (s->vga.ar_flip_flop << 7);
  1479. case 0x19: // Interlace End
  1480. case 0x1a: // Miscellaneous Control
  1481. case 0x1b: // Extended Display Control
  1482. case 0x1c: // Sync Adjust and Genlock
  1483. case 0x1d: // Overlay Extended Control
  1484. case 0x22: // Graphics Data Latches Readback (R)
  1485. case 0x25: // Part Status
  1486. case 0x27: // Part ID (R)
  1487. return s->vga.cr[s->vga.cr_index];
  1488. case 0x26: // Attribute Controller Index Readback (R)
  1489. return s->vga.ar_index & 0x3f;
  1490. default:
  1491. qemu_log_mask(LOG_GUEST_ERROR,
  1492. "cirrus: inport cr_index 0x%02x\n", reg_index);
  1493. return 0xff;
  1494. }
  1495. }
  1496. static void cirrus_vga_write_cr(CirrusVGAState * s, int reg_value)
  1497. {
  1498. switch (s->vga.cr_index) {
  1499. case 0x00: // Standard VGA
  1500. case 0x01: // Standard VGA
  1501. case 0x02: // Standard VGA
  1502. case 0x03: // Standard VGA
  1503. case 0x04: // Standard VGA
  1504. case 0x05: // Standard VGA
  1505. case 0x06: // Standard VGA
  1506. case 0x07: // Standard VGA
  1507. case 0x08: // Standard VGA
  1508. case 0x09: // Standard VGA
  1509. case 0x0a: // Standard VGA
  1510. case 0x0b: // Standard VGA
  1511. case 0x0c: // Standard VGA
  1512. case 0x0d: // Standard VGA
  1513. case 0x0e: // Standard VGA
  1514. case 0x0f: // Standard VGA
  1515. case 0x10: // Standard VGA
  1516. case 0x11: // Standard VGA
  1517. case 0x12: // Standard VGA
  1518. case 0x13: // Standard VGA
  1519. case 0x14: // Standard VGA
  1520. case 0x15: // Standard VGA
  1521. case 0x16: // Standard VGA
  1522. case 0x17: // Standard VGA
  1523. case 0x18: // Standard VGA
  1524. /* handle CR0-7 protection */
  1525. if ((s->vga.cr[0x11] & 0x80) && s->vga.cr_index <= 7) {
  1526. /* can always write bit 4 of CR7 */
  1527. if (s->vga.cr_index == 7)
  1528. s->vga.cr[7] = (s->vga.cr[7] & ~0x10) | (reg_value & 0x10);
  1529. return;
  1530. }
  1531. s->vga.cr[s->vga.cr_index] = reg_value;
  1532. switch(s->vga.cr_index) {
  1533. case 0x00:
  1534. case 0x04:
  1535. case 0x05:
  1536. case 0x06:
  1537. case 0x07:
  1538. case 0x11:
  1539. case 0x17:
  1540. s->vga.update_retrace_info(&s->vga);
  1541. break;
  1542. }
  1543. break;
  1544. case 0x19: // Interlace End
  1545. case 0x1a: // Miscellaneous Control
  1546. case 0x1b: // Extended Display Control
  1547. case 0x1c: // Sync Adjust and Genlock
  1548. case 0x1d: // Overlay Extended Control
  1549. s->vga.cr[s->vga.cr_index] = reg_value;
  1550. #ifdef DEBUG_CIRRUS
  1551. printf("cirrus: handled outport cr_index %02x, cr_value %02x\n",
  1552. s->vga.cr_index, reg_value);
  1553. #endif
  1554. break;
  1555. case 0x22: // Graphics Data Latches Readback (R)
  1556. case 0x24: // Attribute Controller Toggle Readback (R)
  1557. case 0x26: // Attribute Controller Index Readback (R)
  1558. case 0x27: // Part ID (R)
  1559. break;
  1560. case 0x25: // Part Status
  1561. default:
  1562. qemu_log_mask(LOG_GUEST_ERROR,
  1563. "cirrus: outport cr_index 0x%02x, cr_value 0x%02x\n",
  1564. s->vga.cr_index, reg_value);
  1565. break;
  1566. }
  1567. }
  1568. /***************************************
  1569. *
  1570. * memory-mapped I/O (bitblt)
  1571. *
  1572. ***************************************/
  1573. static uint8_t cirrus_mmio_blt_read(CirrusVGAState * s, unsigned address)
  1574. {
  1575. int value = 0xff;
  1576. switch (address) {
  1577. case (CIRRUS_MMIO_BLTBGCOLOR + 0):
  1578. value = cirrus_vga_read_gr(s, 0x00);
  1579. break;
  1580. case (CIRRUS_MMIO_BLTBGCOLOR + 1):
  1581. value = cirrus_vga_read_gr(s, 0x10);
  1582. break;
  1583. case (CIRRUS_MMIO_BLTBGCOLOR + 2):
  1584. value = cirrus_vga_read_gr(s, 0x12);
  1585. break;
  1586. case (CIRRUS_MMIO_BLTBGCOLOR + 3):
  1587. value = cirrus_vga_read_gr(s, 0x14);
  1588. break;
  1589. case (CIRRUS_MMIO_BLTFGCOLOR + 0):
  1590. value = cirrus_vga_read_gr(s, 0x01);
  1591. break;
  1592. case (CIRRUS_MMIO_BLTFGCOLOR + 1):
  1593. value = cirrus_vga_read_gr(s, 0x11);
  1594. break;
  1595. case (CIRRUS_MMIO_BLTFGCOLOR + 2):
  1596. value = cirrus_vga_read_gr(s, 0x13);
  1597. break;
  1598. case (CIRRUS_MMIO_BLTFGCOLOR + 3):
  1599. value = cirrus_vga_read_gr(s, 0x15);
  1600. break;
  1601. case (CIRRUS_MMIO_BLTWIDTH + 0):
  1602. value = cirrus_vga_read_gr(s, 0x20);
  1603. break;
  1604. case (CIRRUS_MMIO_BLTWIDTH + 1):
  1605. value = cirrus_vga_read_gr(s, 0x21);
  1606. break;
  1607. case (CIRRUS_MMIO_BLTHEIGHT + 0):
  1608. value = cirrus_vga_read_gr(s, 0x22);
  1609. break;
  1610. case (CIRRUS_MMIO_BLTHEIGHT + 1):
  1611. value = cirrus_vga_read_gr(s, 0x23);
  1612. break;
  1613. case (CIRRUS_MMIO_BLTDESTPITCH + 0):
  1614. value = cirrus_vga_read_gr(s, 0x24);
  1615. break;
  1616. case (CIRRUS_MMIO_BLTDESTPITCH + 1):
  1617. value = cirrus_vga_read_gr(s, 0x25);
  1618. break;
  1619. case (CIRRUS_MMIO_BLTSRCPITCH + 0):
  1620. value = cirrus_vga_read_gr(s, 0x26);
  1621. break;
  1622. case (CIRRUS_MMIO_BLTSRCPITCH + 1):
  1623. value = cirrus_vga_read_gr(s, 0x27);
  1624. break;
  1625. case (CIRRUS_MMIO_BLTDESTADDR + 0):
  1626. value = cirrus_vga_read_gr(s, 0x28);
  1627. break;
  1628. case (CIRRUS_MMIO_BLTDESTADDR + 1):
  1629. value = cirrus_vga_read_gr(s, 0x29);
  1630. break;
  1631. case (CIRRUS_MMIO_BLTDESTADDR + 2):
  1632. value = cirrus_vga_read_gr(s, 0x2a);
  1633. break;
  1634. case (CIRRUS_MMIO_BLTSRCADDR + 0):
  1635. value = cirrus_vga_read_gr(s, 0x2c);
  1636. break;
  1637. case (CIRRUS_MMIO_BLTSRCADDR + 1):
  1638. value = cirrus_vga_read_gr(s, 0x2d);
  1639. break;
  1640. case (CIRRUS_MMIO_BLTSRCADDR + 2):
  1641. value = cirrus_vga_read_gr(s, 0x2e);
  1642. break;
  1643. case CIRRUS_MMIO_BLTWRITEMASK:
  1644. value = cirrus_vga_read_gr(s, 0x2f);
  1645. break;
  1646. case CIRRUS_MMIO_BLTMODE:
  1647. value = cirrus_vga_read_gr(s, 0x30);
  1648. break;
  1649. case CIRRUS_MMIO_BLTROP:
  1650. value = cirrus_vga_read_gr(s, 0x32);
  1651. break;
  1652. case CIRRUS_MMIO_BLTMODEEXT:
  1653. value = cirrus_vga_read_gr(s, 0x33);
  1654. break;
  1655. case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0):
  1656. value = cirrus_vga_read_gr(s, 0x34);
  1657. break;
  1658. case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1):
  1659. value = cirrus_vga_read_gr(s, 0x35);
  1660. break;
  1661. case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0):
  1662. value = cirrus_vga_read_gr(s, 0x38);
  1663. break;
  1664. case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1):
  1665. value = cirrus_vga_read_gr(s, 0x39);
  1666. break;
  1667. case CIRRUS_MMIO_BLTSTATUS:
  1668. value = cirrus_vga_read_gr(s, 0x31);
  1669. break;
  1670. default:
  1671. qemu_log_mask(LOG_GUEST_ERROR,
  1672. "cirrus: mmio read - address 0x%04x\n", address);
  1673. break;
  1674. }
  1675. trace_vga_cirrus_write_blt(address, value);
  1676. return (uint8_t) value;
  1677. }
  1678. static void cirrus_mmio_blt_write(CirrusVGAState * s, unsigned address,
  1679. uint8_t value)
  1680. {
  1681. trace_vga_cirrus_write_blt(address, value);
  1682. switch (address) {
  1683. case (CIRRUS_MMIO_BLTBGCOLOR + 0):
  1684. cirrus_vga_write_gr(s, 0x00, value);
  1685. break;
  1686. case (CIRRUS_MMIO_BLTBGCOLOR + 1):
  1687. cirrus_vga_write_gr(s, 0x10, value);
  1688. break;
  1689. case (CIRRUS_MMIO_BLTBGCOLOR + 2):
  1690. cirrus_vga_write_gr(s, 0x12, value);
  1691. break;
  1692. case (CIRRUS_MMIO_BLTBGCOLOR + 3):
  1693. cirrus_vga_write_gr(s, 0x14, value);
  1694. break;
  1695. case (CIRRUS_MMIO_BLTFGCOLOR + 0):
  1696. cirrus_vga_write_gr(s, 0x01, value);
  1697. break;
  1698. case (CIRRUS_MMIO_BLTFGCOLOR + 1):
  1699. cirrus_vga_write_gr(s, 0x11, value);
  1700. break;
  1701. case (CIRRUS_MMIO_BLTFGCOLOR + 2):
  1702. cirrus_vga_write_gr(s, 0x13, value);
  1703. break;
  1704. case (CIRRUS_MMIO_BLTFGCOLOR + 3):
  1705. cirrus_vga_write_gr(s, 0x15, value);
  1706. break;
  1707. case (CIRRUS_MMIO_BLTWIDTH + 0):
  1708. cirrus_vga_write_gr(s, 0x20, value);
  1709. break;
  1710. case (CIRRUS_MMIO_BLTWIDTH + 1):
  1711. cirrus_vga_write_gr(s, 0x21, value);
  1712. break;
  1713. case (CIRRUS_MMIO_BLTHEIGHT + 0):
  1714. cirrus_vga_write_gr(s, 0x22, value);
  1715. break;
  1716. case (CIRRUS_MMIO_BLTHEIGHT + 1):
  1717. cirrus_vga_write_gr(s, 0x23, value);
  1718. break;
  1719. case (CIRRUS_MMIO_BLTDESTPITCH + 0):
  1720. cirrus_vga_write_gr(s, 0x24, value);
  1721. break;
  1722. case (CIRRUS_MMIO_BLTDESTPITCH + 1):
  1723. cirrus_vga_write_gr(s, 0x25, value);
  1724. break;
  1725. case (CIRRUS_MMIO_BLTSRCPITCH + 0):
  1726. cirrus_vga_write_gr(s, 0x26, value);
  1727. break;
  1728. case (CIRRUS_MMIO_BLTSRCPITCH + 1):
  1729. cirrus_vga_write_gr(s, 0x27, value);
  1730. break;
  1731. case (CIRRUS_MMIO_BLTDESTADDR + 0):
  1732. cirrus_vga_write_gr(s, 0x28, value);
  1733. break;
  1734. case (CIRRUS_MMIO_BLTDESTADDR + 1):
  1735. cirrus_vga_write_gr(s, 0x29, value);
  1736. break;
  1737. case (CIRRUS_MMIO_BLTDESTADDR + 2):
  1738. cirrus_vga_write_gr(s, 0x2a, value);
  1739. break;
  1740. case (CIRRUS_MMIO_BLTDESTADDR + 3):
  1741. /* ignored */
  1742. break;
  1743. case (CIRRUS_MMIO_BLTSRCADDR + 0):
  1744. cirrus_vga_write_gr(s, 0x2c, value);
  1745. break;
  1746. case (CIRRUS_MMIO_BLTSRCADDR + 1):
  1747. cirrus_vga_write_gr(s, 0x2d, value);
  1748. break;
  1749. case (CIRRUS_MMIO_BLTSRCADDR + 2):
  1750. cirrus_vga_write_gr(s, 0x2e, value);
  1751. break;
  1752. case CIRRUS_MMIO_BLTWRITEMASK:
  1753. cirrus_vga_write_gr(s, 0x2f, value);
  1754. break;
  1755. case CIRRUS_MMIO_BLTMODE:
  1756. cirrus_vga_write_gr(s, 0x30, value);
  1757. break;
  1758. case CIRRUS_MMIO_BLTROP:
  1759. cirrus_vga_write_gr(s, 0x32, value);
  1760. break;
  1761. case CIRRUS_MMIO_BLTMODEEXT:
  1762. cirrus_vga_write_gr(s, 0x33, value);
  1763. break;
  1764. case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0):
  1765. cirrus_vga_write_gr(s, 0x34, value);
  1766. break;
  1767. case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1):
  1768. cirrus_vga_write_gr(s, 0x35, value);
  1769. break;
  1770. case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0):
  1771. cirrus_vga_write_gr(s, 0x38, value);
  1772. break;
  1773. case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1):
  1774. cirrus_vga_write_gr(s, 0x39, value);
  1775. break;
  1776. case CIRRUS_MMIO_BLTSTATUS:
  1777. cirrus_vga_write_gr(s, 0x31, value);
  1778. break;
  1779. default:
  1780. qemu_log_mask(LOG_GUEST_ERROR,
  1781. "cirrus: mmio write - addr 0x%04x val 0x%02x (ignored)\n",
  1782. address, value);
  1783. break;
  1784. }
  1785. }
  1786. /***************************************
  1787. *
  1788. * write mode 4/5
  1789. *
  1790. ***************************************/
  1791. static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s,
  1792. unsigned mode,
  1793. unsigned offset,
  1794. uint32_t mem_value)
  1795. {
  1796. int x;
  1797. unsigned val = mem_value;
  1798. uint8_t *dst;
  1799. for (x = 0; x < 8; x++) {
  1800. dst = s->vga.vram_ptr + ((offset + x) & s->cirrus_addr_mask);
  1801. if (val & 0x80) {
  1802. *dst = s->cirrus_shadow_gr1;
  1803. } else if (mode == 5) {
  1804. *dst = s->cirrus_shadow_gr0;
  1805. }
  1806. val <<= 1;
  1807. }
  1808. memory_region_set_dirty(&s->vga.vram, offset, 8);
  1809. }
  1810. static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
  1811. unsigned mode,
  1812. unsigned offset,
  1813. uint32_t mem_value)
  1814. {
  1815. int x;
  1816. unsigned val = mem_value;
  1817. uint8_t *dst;
  1818. for (x = 0; x < 8; x++) {
  1819. dst = s->vga.vram_ptr + ((offset + 2 * x) & s->cirrus_addr_mask & ~1);
  1820. if (val & 0x80) {
  1821. *dst = s->cirrus_shadow_gr1;
  1822. *(dst + 1) = s->vga.gr[0x11];
  1823. } else if (mode == 5) {
  1824. *dst = s->cirrus_shadow_gr0;
  1825. *(dst + 1) = s->vga.gr[0x10];
  1826. }
  1827. val <<= 1;
  1828. }
  1829. memory_region_set_dirty(&s->vga.vram, offset, 16);
  1830. }
  1831. /***************************************
  1832. *
  1833. * memory access between 0xa0000-0xbffff
  1834. *
  1835. ***************************************/
  1836. static uint64_t cirrus_vga_mem_read(void *opaque,
  1837. hwaddr addr,
  1838. uint32_t size)
  1839. {
  1840. CirrusVGAState *s = opaque;
  1841. unsigned bank_index;
  1842. unsigned bank_offset;
  1843. uint32_t val;
  1844. if ((s->vga.sr[0x07] & 0x01) == 0) {
  1845. return vga_mem_readb(&s->vga, addr);
  1846. }
  1847. if (addr < 0x10000) {
  1848. /* XXX handle bitblt */
  1849. /* video memory */
  1850. bank_index = addr >> 15;
  1851. bank_offset = addr & 0x7fff;
  1852. if (bank_offset < s->cirrus_bank_limit[bank_index]) {
  1853. bank_offset += s->cirrus_bank_base[bank_index];
  1854. if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
  1855. bank_offset <<= 4;
  1856. } else if (s->vga.gr[0x0B] & 0x02) {
  1857. bank_offset <<= 3;
  1858. }
  1859. bank_offset &= s->cirrus_addr_mask;
  1860. val = *(s->vga.vram_ptr + bank_offset);
  1861. } else
  1862. val = 0xff;
  1863. } else if (addr >= 0x18000 && addr < 0x18100) {
  1864. /* memory-mapped I/O */
  1865. val = 0xff;
  1866. if ((s->vga.sr[0x17] & 0x44) == 0x04) {
  1867. val = cirrus_mmio_blt_read(s, addr & 0xff);
  1868. }
  1869. } else {
  1870. val = 0xff;
  1871. qemu_log_mask(LOG_GUEST_ERROR,
  1872. "cirrus: mem_readb 0x" TARGET_FMT_plx "\n", addr);
  1873. }
  1874. return val;
  1875. }
  1876. static void cirrus_vga_mem_write(void *opaque,
  1877. hwaddr addr,
  1878. uint64_t mem_value,
  1879. uint32_t size)
  1880. {
  1881. CirrusVGAState *s = opaque;
  1882. unsigned bank_index;
  1883. unsigned bank_offset;
  1884. unsigned mode;
  1885. if ((s->vga.sr[0x07] & 0x01) == 0) {
  1886. vga_mem_writeb(&s->vga, addr, mem_value);
  1887. return;
  1888. }
  1889. if (addr < 0x10000) {
  1890. if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
  1891. /* bitblt */
  1892. *s->cirrus_srcptr++ = (uint8_t) mem_value;
  1893. if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
  1894. cirrus_bitblt_cputovideo_next(s);
  1895. }
  1896. } else {
  1897. /* video memory */
  1898. bank_index = addr >> 15;
  1899. bank_offset = addr & 0x7fff;
  1900. if (bank_offset < s->cirrus_bank_limit[bank_index]) {
  1901. bank_offset += s->cirrus_bank_base[bank_index];
  1902. if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
  1903. bank_offset <<= 4;
  1904. } else if (s->vga.gr[0x0B] & 0x02) {
  1905. bank_offset <<= 3;
  1906. }
  1907. bank_offset &= s->cirrus_addr_mask;
  1908. mode = s->vga.gr[0x05] & 0x7;
  1909. if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
  1910. *(s->vga.vram_ptr + bank_offset) = mem_value;
  1911. memory_region_set_dirty(&s->vga.vram, bank_offset,
  1912. sizeof(mem_value));
  1913. } else {
  1914. if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
  1915. cirrus_mem_writeb_mode4and5_8bpp(s, mode,
  1916. bank_offset,
  1917. mem_value);
  1918. } else {
  1919. cirrus_mem_writeb_mode4and5_16bpp(s, mode,
  1920. bank_offset,
  1921. mem_value);
  1922. }
  1923. }
  1924. }
  1925. }
  1926. } else if (addr >= 0x18000 && addr < 0x18100) {
  1927. /* memory-mapped I/O */
  1928. if ((s->vga.sr[0x17] & 0x44) == 0x04) {
  1929. cirrus_mmio_blt_write(s, addr & 0xff, mem_value);
  1930. }
  1931. } else {
  1932. qemu_log_mask(LOG_GUEST_ERROR,
  1933. "cirrus: mem_writeb 0x" TARGET_FMT_plx " "
  1934. "value 0x%02" PRIx64 "\n", addr, mem_value);
  1935. }
  1936. }
  1937. static const MemoryRegionOps cirrus_vga_mem_ops = {
  1938. .read = cirrus_vga_mem_read,
  1939. .write = cirrus_vga_mem_write,
  1940. .endianness = DEVICE_LITTLE_ENDIAN,
  1941. .impl = {
  1942. .min_access_size = 1,
  1943. .max_access_size = 1,
  1944. },
  1945. };
  1946. /***************************************
  1947. *
  1948. * hardware cursor
  1949. *
  1950. ***************************************/
  1951. static inline void invalidate_cursor1(CirrusVGAState *s)
  1952. {
  1953. if (s->last_hw_cursor_size) {
  1954. vga_invalidate_scanlines(&s->vga,
  1955. s->last_hw_cursor_y + s->last_hw_cursor_y_start,
  1956. s->last_hw_cursor_y + s->last_hw_cursor_y_end);
  1957. }
  1958. }
  1959. static inline void cirrus_cursor_compute_yrange(CirrusVGAState *s)
  1960. {
  1961. const uint8_t *src;
  1962. uint32_t content;
  1963. int y, y_min, y_max;
  1964. src = s->vga.vram_ptr + s->real_vram_size - 16 * KiB;
  1965. if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) {
  1966. src += (s->vga.sr[0x13] & 0x3c) * 256;
  1967. y_min = 64;
  1968. y_max = -1;
  1969. for(y = 0; y < 64; y++) {
  1970. content = ((uint32_t *)src)[0] |
  1971. ((uint32_t *)src)[1] |
  1972. ((uint32_t *)src)[2] |
  1973. ((uint32_t *)src)[3];
  1974. if (content) {
  1975. if (y < y_min)
  1976. y_min = y;
  1977. if (y > y_max)
  1978. y_max = y;
  1979. }
  1980. src += 16;
  1981. }
  1982. } else {
  1983. src += (s->vga.sr[0x13] & 0x3f) * 256;
  1984. y_min = 32;
  1985. y_max = -1;
  1986. for(y = 0; y < 32; y++) {
  1987. content = ((uint32_t *)src)[0] |
  1988. ((uint32_t *)(src + 128))[0];
  1989. if (content) {
  1990. if (y < y_min)
  1991. y_min = y;
  1992. if (y > y_max)
  1993. y_max = y;
  1994. }
  1995. src += 4;
  1996. }
  1997. }
  1998. if (y_min > y_max) {
  1999. s->last_hw_cursor_y_start = 0;
  2000. s->last_hw_cursor_y_end = 0;
  2001. } else {
  2002. s->last_hw_cursor_y_start = y_min;
  2003. s->last_hw_cursor_y_end = y_max + 1;
  2004. }
  2005. }
  2006. /* NOTE: we do not currently handle the cursor bitmap change, so we
  2007. update the cursor only if it moves. */
  2008. static void cirrus_cursor_invalidate(VGACommonState *s1)
  2009. {
  2010. CirrusVGAState *s = container_of(s1, CirrusVGAState, vga);
  2011. int size;
  2012. if (!(s->vga.sr[0x12] & CIRRUS_CURSOR_SHOW)) {
  2013. size = 0;
  2014. } else {
  2015. if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE)
  2016. size = 64;
  2017. else
  2018. size = 32;
  2019. }
  2020. /* invalidate last cursor and new cursor if any change */
  2021. if (s->last_hw_cursor_size != size ||
  2022. s->last_hw_cursor_x != s->vga.hw_cursor_x ||
  2023. s->last_hw_cursor_y != s->vga.hw_cursor_y) {
  2024. invalidate_cursor1(s);
  2025. s->last_hw_cursor_size = size;
  2026. s->last_hw_cursor_x = s->vga.hw_cursor_x;
  2027. s->last_hw_cursor_y = s->vga.hw_cursor_y;
  2028. /* compute the real cursor min and max y */
  2029. cirrus_cursor_compute_yrange(s);
  2030. invalidate_cursor1(s);
  2031. }
  2032. }
  2033. static void vga_draw_cursor_line(uint8_t *d1,
  2034. const uint8_t *src1,
  2035. int poffset, int w,
  2036. unsigned int color0,
  2037. unsigned int color1,
  2038. unsigned int color_xor)
  2039. {
  2040. const uint8_t *plane0, *plane1;
  2041. int x, b0, b1;
  2042. uint8_t *d;
  2043. d = d1;
  2044. plane0 = src1;
  2045. plane1 = src1 + poffset;
  2046. for (x = 0; x < w; x++) {
  2047. b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1;
  2048. b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1;
  2049. switch (b0 | (b1 << 1)) {
  2050. case 0:
  2051. break;
  2052. case 1:
  2053. ((uint32_t *)d)[0] ^= color_xor;
  2054. break;
  2055. case 2:
  2056. ((uint32_t *)d)[0] = color0;
  2057. break;
  2058. case 3:
  2059. ((uint32_t *)d)[0] = color1;
  2060. break;
  2061. }
  2062. d += 4;
  2063. }
  2064. }
  2065. static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y)
  2066. {
  2067. CirrusVGAState *s = container_of(s1, CirrusVGAState, vga);
  2068. int w, h, x1, x2, poffset;
  2069. unsigned int color0, color1;
  2070. const uint8_t *palette, *src;
  2071. uint32_t content;
  2072. if (!(s->vga.sr[0x12] & CIRRUS_CURSOR_SHOW))
  2073. return;
  2074. /* fast test to see if the cursor intersects with the scan line */
  2075. if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) {
  2076. h = 64;
  2077. } else {
  2078. h = 32;
  2079. }
  2080. if (scr_y < s->vga.hw_cursor_y ||
  2081. scr_y >= (s->vga.hw_cursor_y + h)) {
  2082. return;
  2083. }
  2084. src = s->vga.vram_ptr + s->real_vram_size - 16 * KiB;
  2085. if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) {
  2086. src += (s->vga.sr[0x13] & 0x3c) * 256;
  2087. src += (scr_y - s->vga.hw_cursor_y) * 16;
  2088. poffset = 8;
  2089. content = ((uint32_t *)src)[0] |
  2090. ((uint32_t *)src)[1] |
  2091. ((uint32_t *)src)[2] |
  2092. ((uint32_t *)src)[3];
  2093. } else {
  2094. src += (s->vga.sr[0x13] & 0x3f) * 256;
  2095. src += (scr_y - s->vga.hw_cursor_y) * 4;
  2096. poffset = 128;
  2097. content = ((uint32_t *)src)[0] |
  2098. ((uint32_t *)(src + 128))[0];
  2099. }
  2100. /* if nothing to draw, no need to continue */
  2101. if (!content)
  2102. return;
  2103. w = h;
  2104. x1 = s->vga.hw_cursor_x;
  2105. if (x1 >= s->vga.last_scr_width)
  2106. return;
  2107. x2 = s->vga.hw_cursor_x + w;
  2108. if (x2 > s->vga.last_scr_width)
  2109. x2 = s->vga.last_scr_width;
  2110. w = x2 - x1;
  2111. palette = s->cirrus_hidden_palette;
  2112. color0 = rgb_to_pixel32(c6_to_8(palette[0x0 * 3]),
  2113. c6_to_8(palette[0x0 * 3 + 1]),
  2114. c6_to_8(palette[0x0 * 3 + 2]));
  2115. color1 = rgb_to_pixel32(c6_to_8(palette[0xf * 3]),
  2116. c6_to_8(palette[0xf * 3 + 1]),
  2117. c6_to_8(palette[0xf * 3 + 2]));
  2118. d1 += x1 * 4;
  2119. vga_draw_cursor_line(d1, src, poffset, w, color0, color1, 0xffffff);
  2120. }
  2121. /***************************************
  2122. *
  2123. * LFB memory access
  2124. *
  2125. ***************************************/
  2126. static uint64_t cirrus_linear_read(void *opaque, hwaddr addr,
  2127. unsigned size)
  2128. {
  2129. CirrusVGAState *s = opaque;
  2130. uint32_t ret;
  2131. addr &= s->cirrus_addr_mask;
  2132. if (((s->vga.sr[0x17] & 0x44) == 0x44) &&
  2133. ((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) {
  2134. /* memory-mapped I/O */
  2135. ret = cirrus_mmio_blt_read(s, addr & 0xff);
  2136. } else if (0) {
  2137. /* XXX handle bitblt */
  2138. ret = 0xff;
  2139. } else {
  2140. /* video memory */
  2141. if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
  2142. addr <<= 4;
  2143. } else if (s->vga.gr[0x0B] & 0x02) {
  2144. addr <<= 3;
  2145. }
  2146. addr &= s->cirrus_addr_mask;
  2147. ret = *(s->vga.vram_ptr + addr);
  2148. }
  2149. return ret;
  2150. }
  2151. static void cirrus_linear_write(void *opaque, hwaddr addr,
  2152. uint64_t val, unsigned size)
  2153. {
  2154. CirrusVGAState *s = opaque;
  2155. unsigned mode;
  2156. addr &= s->cirrus_addr_mask;
  2157. if (((s->vga.sr[0x17] & 0x44) == 0x44) &&
  2158. ((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) {
  2159. /* memory-mapped I/O */
  2160. cirrus_mmio_blt_write(s, addr & 0xff, val);
  2161. } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
  2162. /* bitblt */
  2163. *s->cirrus_srcptr++ = (uint8_t) val;
  2164. if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
  2165. cirrus_bitblt_cputovideo_next(s);
  2166. }
  2167. } else {
  2168. /* video memory */
  2169. if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
  2170. addr <<= 4;
  2171. } else if (s->vga.gr[0x0B] & 0x02) {
  2172. addr <<= 3;
  2173. }
  2174. addr &= s->cirrus_addr_mask;
  2175. mode = s->vga.gr[0x05] & 0x7;
  2176. if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
  2177. *(s->vga.vram_ptr + addr) = (uint8_t) val;
  2178. memory_region_set_dirty(&s->vga.vram, addr, 1);
  2179. } else {
  2180. if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
  2181. cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val);
  2182. } else {
  2183. cirrus_mem_writeb_mode4and5_16bpp(s, mode, addr, val);
  2184. }
  2185. }
  2186. }
  2187. }
  2188. /***************************************
  2189. *
  2190. * system to screen memory access
  2191. *
  2192. ***************************************/
  2193. static uint64_t cirrus_linear_bitblt_read(void *opaque,
  2194. hwaddr addr,
  2195. unsigned size)
  2196. {
  2197. CirrusVGAState *s = opaque;
  2198. /* XXX handle bitblt */
  2199. (void)s;
  2200. qemu_log_mask(LOG_UNIMP,
  2201. "cirrus: linear bitblt is not implemented\n");
  2202. return 0xff;
  2203. }
  2204. static void cirrus_linear_bitblt_write(void *opaque,
  2205. hwaddr addr,
  2206. uint64_t val,
  2207. unsigned size)
  2208. {
  2209. CirrusVGAState *s = opaque;
  2210. if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
  2211. /* bitblt */
  2212. *s->cirrus_srcptr++ = (uint8_t) val;
  2213. if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
  2214. cirrus_bitblt_cputovideo_next(s);
  2215. }
  2216. }
  2217. }
  2218. static const MemoryRegionOps cirrus_linear_bitblt_io_ops = {
  2219. .read = cirrus_linear_bitblt_read,
  2220. .write = cirrus_linear_bitblt_write,
  2221. .endianness = DEVICE_LITTLE_ENDIAN,
  2222. .impl = {
  2223. .min_access_size = 1,
  2224. .max_access_size = 1,
  2225. },
  2226. };
  2227. static void map_linear_vram_bank(CirrusVGAState *s, unsigned bank)
  2228. {
  2229. MemoryRegion *mr = &s->cirrus_bank[bank];
  2230. bool enabled = !(s->cirrus_srcptr != s->cirrus_srcptr_end)
  2231. && !((s->vga.sr[0x07] & 0x01) == 0)
  2232. && !((s->vga.gr[0x0B] & 0x14) == 0x14)
  2233. && !(s->vga.gr[0x0B] & 0x02);
  2234. memory_region_set_enabled(mr, enabled);
  2235. memory_region_set_alias_offset(mr, s->cirrus_bank_base[bank]);
  2236. }
  2237. static void map_linear_vram(CirrusVGAState *s)
  2238. {
  2239. if (s->bustype == CIRRUS_BUSTYPE_PCI && !s->linear_vram) {
  2240. s->linear_vram = true;
  2241. memory_region_add_subregion_overlap(&s->pci_bar, 0, &s->vga.vram, 1);
  2242. }
  2243. map_linear_vram_bank(s, 0);
  2244. map_linear_vram_bank(s, 1);
  2245. }
  2246. static void unmap_linear_vram(CirrusVGAState *s)
  2247. {
  2248. if (s->bustype == CIRRUS_BUSTYPE_PCI && s->linear_vram) {
  2249. s->linear_vram = false;
  2250. memory_region_del_subregion(&s->pci_bar, &s->vga.vram);
  2251. }
  2252. memory_region_set_enabled(&s->cirrus_bank[0], false);
  2253. memory_region_set_enabled(&s->cirrus_bank[1], false);
  2254. }
  2255. /* Compute the memory access functions */
  2256. static void cirrus_update_memory_access(CirrusVGAState *s)
  2257. {
  2258. unsigned mode;
  2259. memory_region_transaction_begin();
  2260. if ((s->vga.sr[0x17] & 0x44) == 0x44) {
  2261. goto generic_io;
  2262. } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
  2263. goto generic_io;
  2264. } else {
  2265. if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
  2266. goto generic_io;
  2267. } else if (s->vga.gr[0x0B] & 0x02) {
  2268. goto generic_io;
  2269. }
  2270. mode = s->vga.gr[0x05] & 0x7;
  2271. if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
  2272. map_linear_vram(s);
  2273. } else {
  2274. generic_io:
  2275. unmap_linear_vram(s);
  2276. }
  2277. }
  2278. memory_region_transaction_commit();
  2279. }
  2280. /* I/O ports */
  2281. static uint64_t cirrus_vga_ioport_read(void *opaque, hwaddr addr,
  2282. unsigned size)
  2283. {
  2284. CirrusVGAState *c = opaque;
  2285. VGACommonState *s = &c->vga;
  2286. int val, index;
  2287. addr += 0x3b0;
  2288. if (vga_ioport_invalid(s, addr)) {
  2289. val = 0xff;
  2290. } else {
  2291. switch (addr) {
  2292. case 0x3c0:
  2293. if (s->ar_flip_flop == 0) {
  2294. val = s->ar_index;
  2295. } else {
  2296. val = 0;
  2297. }
  2298. break;
  2299. case 0x3c1:
  2300. index = s->ar_index & 0x1f;
  2301. if (index < 21)
  2302. val = s->ar[index];
  2303. else
  2304. val = 0;
  2305. break;
  2306. case 0x3c2:
  2307. val = s->st00;
  2308. break;
  2309. case 0x3c4:
  2310. val = s->sr_index;
  2311. break;
  2312. case 0x3c5:
  2313. val = cirrus_vga_read_sr(c);
  2314. break;
  2315. break;
  2316. case 0x3c6:
  2317. val = cirrus_read_hidden_dac(c);
  2318. break;
  2319. case 0x3c7:
  2320. val = s->dac_state;
  2321. break;
  2322. case 0x3c8:
  2323. val = s->dac_write_index;
  2324. c->cirrus_hidden_dac_lockindex = 0;
  2325. break;
  2326. case 0x3c9:
  2327. val = cirrus_vga_read_palette(c);
  2328. break;
  2329. case 0x3ca:
  2330. val = s->fcr;
  2331. break;
  2332. case 0x3cc:
  2333. val = s->msr;
  2334. break;
  2335. case 0x3ce:
  2336. val = s->gr_index;
  2337. break;
  2338. case 0x3cf:
  2339. val = cirrus_vga_read_gr(c, s->gr_index);
  2340. break;
  2341. case 0x3b4:
  2342. case 0x3d4:
  2343. val = s->cr_index;
  2344. break;
  2345. case 0x3b5:
  2346. case 0x3d5:
  2347. val = cirrus_vga_read_cr(c, s->cr_index);
  2348. break;
  2349. case 0x3ba:
  2350. case 0x3da:
  2351. /* just toggle to fool polling */
  2352. val = s->st01 = s->retrace(s);
  2353. s->ar_flip_flop = 0;
  2354. break;
  2355. default:
  2356. val = 0x00;
  2357. break;
  2358. }
  2359. }
  2360. trace_vga_cirrus_read_io(addr, val);
  2361. return val;
  2362. }
  2363. static void cirrus_vga_ioport_write(void *opaque, hwaddr addr, uint64_t val,
  2364. unsigned size)
  2365. {
  2366. CirrusVGAState *c = opaque;
  2367. VGACommonState *s = &c->vga;
  2368. int index;
  2369. addr += 0x3b0;
  2370. /* check port range access depending on color/monochrome mode */
  2371. if (vga_ioport_invalid(s, addr)) {
  2372. return;
  2373. }
  2374. trace_vga_cirrus_write_io(addr, val);
  2375. switch (addr) {
  2376. case 0x3c0:
  2377. if (s->ar_flip_flop == 0) {
  2378. val &= 0x3f;
  2379. s->ar_index = val;
  2380. } else {
  2381. index = s->ar_index & 0x1f;
  2382. switch (index) {
  2383. case 0x00 ... 0x0f:
  2384. s->ar[index] = val & 0x3f;
  2385. break;
  2386. case 0x10:
  2387. s->ar[index] = val & ~0x10;
  2388. break;
  2389. case 0x11:
  2390. s->ar[index] = val;
  2391. break;
  2392. case 0x12:
  2393. s->ar[index] = val & ~0xc0;
  2394. break;
  2395. case 0x13:
  2396. s->ar[index] = val & ~0xf0;
  2397. break;
  2398. case 0x14:
  2399. s->ar[index] = val & ~0xf0;
  2400. break;
  2401. default:
  2402. break;
  2403. }
  2404. }
  2405. s->ar_flip_flop ^= 1;
  2406. break;
  2407. case 0x3c2:
  2408. s->msr = val & ~0x10;
  2409. s->update_retrace_info(s);
  2410. break;
  2411. case 0x3c4:
  2412. s->sr_index = val;
  2413. break;
  2414. case 0x3c5:
  2415. cirrus_vga_write_sr(c, val);
  2416. break;
  2417. case 0x3c6:
  2418. cirrus_write_hidden_dac(c, val);
  2419. break;
  2420. case 0x3c7:
  2421. s->dac_read_index = val;
  2422. s->dac_sub_index = 0;
  2423. s->dac_state = 3;
  2424. break;
  2425. case 0x3c8:
  2426. s->dac_write_index = val;
  2427. s->dac_sub_index = 0;
  2428. s->dac_state = 0;
  2429. break;
  2430. case 0x3c9:
  2431. cirrus_vga_write_palette(c, val);
  2432. break;
  2433. case 0x3ce:
  2434. s->gr_index = val;
  2435. break;
  2436. case 0x3cf:
  2437. cirrus_vga_write_gr(c, s->gr_index, val);
  2438. break;
  2439. case 0x3b4:
  2440. case 0x3d4:
  2441. s->cr_index = val;
  2442. break;
  2443. case 0x3b5:
  2444. case 0x3d5:
  2445. cirrus_vga_write_cr(c, val);
  2446. break;
  2447. case 0x3ba:
  2448. case 0x3da:
  2449. s->fcr = val & 0x10;
  2450. break;
  2451. }
  2452. }
  2453. /***************************************
  2454. *
  2455. * memory-mapped I/O access
  2456. *
  2457. ***************************************/
  2458. static uint64_t cirrus_mmio_read(void *opaque, hwaddr addr,
  2459. unsigned size)
  2460. {
  2461. CirrusVGAState *s = opaque;
  2462. if (addr >= 0x100) {
  2463. return cirrus_mmio_blt_read(s, addr - 0x100);
  2464. } else {
  2465. return cirrus_vga_ioport_read(s, addr + 0x10, size);
  2466. }
  2467. }
  2468. static void cirrus_mmio_write(void *opaque, hwaddr addr,
  2469. uint64_t val, unsigned size)
  2470. {
  2471. CirrusVGAState *s = opaque;
  2472. if (addr >= 0x100) {
  2473. cirrus_mmio_blt_write(s, addr - 0x100, val);
  2474. } else {
  2475. cirrus_vga_ioport_write(s, addr + 0x10, val, size);
  2476. }
  2477. }
  2478. static const MemoryRegionOps cirrus_mmio_io_ops = {
  2479. .read = cirrus_mmio_read,
  2480. .write = cirrus_mmio_write,
  2481. .endianness = DEVICE_LITTLE_ENDIAN,
  2482. .impl = {
  2483. .min_access_size = 1,
  2484. .max_access_size = 1,
  2485. },
  2486. };
  2487. /* load/save state */
  2488. static int cirrus_post_load(void *opaque, int version_id)
  2489. {
  2490. CirrusVGAState *s = opaque;
  2491. s->vga.gr[0x00] = s->cirrus_shadow_gr0 & 0x0f;
  2492. s->vga.gr[0x01] = s->cirrus_shadow_gr1 & 0x0f;
  2493. cirrus_update_bank_ptr(s, 0);
  2494. cirrus_update_bank_ptr(s, 1);
  2495. cirrus_update_memory_access(s);
  2496. /* force refresh */
  2497. s->vga.graphic_mode = -1;
  2498. return 0;
  2499. }
  2500. const VMStateDescription vmstate_cirrus_vga = {
  2501. .name = "cirrus_vga",
  2502. .version_id = 2,
  2503. .minimum_version_id = 1,
  2504. .post_load = cirrus_post_load,
  2505. .fields = (VMStateField[]) {
  2506. VMSTATE_UINT32(vga.latch, CirrusVGAState),
  2507. VMSTATE_UINT8(vga.sr_index, CirrusVGAState),
  2508. VMSTATE_BUFFER(vga.sr, CirrusVGAState),
  2509. VMSTATE_UINT8(vga.gr_index, CirrusVGAState),
  2510. VMSTATE_UINT8(cirrus_shadow_gr0, CirrusVGAState),
  2511. VMSTATE_UINT8(cirrus_shadow_gr1, CirrusVGAState),
  2512. VMSTATE_BUFFER_START_MIDDLE(vga.gr, CirrusVGAState, 2),
  2513. VMSTATE_UINT8(vga.ar_index, CirrusVGAState),
  2514. VMSTATE_BUFFER(vga.ar, CirrusVGAState),
  2515. VMSTATE_INT32(vga.ar_flip_flop, CirrusVGAState),
  2516. VMSTATE_UINT8(vga.cr_index, CirrusVGAState),
  2517. VMSTATE_BUFFER(vga.cr, CirrusVGAState),
  2518. VMSTATE_UINT8(vga.msr, CirrusVGAState),
  2519. VMSTATE_UINT8(vga.fcr, CirrusVGAState),
  2520. VMSTATE_UINT8(vga.st00, CirrusVGAState),
  2521. VMSTATE_UINT8(vga.st01, CirrusVGAState),
  2522. VMSTATE_UINT8(vga.dac_state, CirrusVGAState),
  2523. VMSTATE_UINT8(vga.dac_sub_index, CirrusVGAState),
  2524. VMSTATE_UINT8(vga.dac_read_index, CirrusVGAState),
  2525. VMSTATE_UINT8(vga.dac_write_index, CirrusVGAState),
  2526. VMSTATE_BUFFER(vga.dac_cache, CirrusVGAState),
  2527. VMSTATE_BUFFER(vga.palette, CirrusVGAState),
  2528. VMSTATE_INT32(vga.bank_offset, CirrusVGAState),
  2529. VMSTATE_UINT8(cirrus_hidden_dac_lockindex, CirrusVGAState),
  2530. VMSTATE_UINT8(cirrus_hidden_dac_data, CirrusVGAState),
  2531. VMSTATE_UINT32(vga.hw_cursor_x, CirrusVGAState),
  2532. VMSTATE_UINT32(vga.hw_cursor_y, CirrusVGAState),
  2533. /* XXX: we do not save the bitblt state - we assume we do not save
  2534. the state when the blitter is active */
  2535. VMSTATE_END_OF_LIST()
  2536. }
  2537. };
  2538. static const VMStateDescription vmstate_pci_cirrus_vga = {
  2539. .name = "cirrus_vga",
  2540. .version_id = 2,
  2541. .minimum_version_id = 2,
  2542. .fields = (VMStateField[]) {
  2543. VMSTATE_PCI_DEVICE(dev, PCICirrusVGAState),
  2544. VMSTATE_STRUCT(cirrus_vga, PCICirrusVGAState, 0,
  2545. vmstate_cirrus_vga, CirrusVGAState),
  2546. VMSTATE_END_OF_LIST()
  2547. }
  2548. };
  2549. /***************************************
  2550. *
  2551. * initialize
  2552. *
  2553. ***************************************/
  2554. static void cirrus_reset(void *opaque)
  2555. {
  2556. CirrusVGAState *s = opaque;
  2557. vga_common_reset(&s->vga);
  2558. unmap_linear_vram(s);
  2559. s->vga.sr[0x06] = 0x0f;
  2560. if (s->device_id == CIRRUS_ID_CLGD5446) {
  2561. /* 4MB 64 bit memory config, always PCI */
  2562. s->vga.sr[0x1F] = 0x2d; // MemClock
  2563. s->vga.gr[0x18] = 0x0f; // fastest memory configuration
  2564. s->vga.sr[0x0f] = 0x98;
  2565. s->vga.sr[0x17] = 0x20;
  2566. s->vga.sr[0x15] = 0x04; /* memory size, 3=2MB, 4=4MB */
  2567. } else {
  2568. s->vga.sr[0x1F] = 0x22; // MemClock
  2569. s->vga.sr[0x0F] = CIRRUS_MEMSIZE_2M;
  2570. s->vga.sr[0x17] = s->bustype;
  2571. s->vga.sr[0x15] = 0x03; /* memory size, 3=2MB, 4=4MB */
  2572. }
  2573. s->vga.cr[0x27] = s->device_id;
  2574. s->cirrus_hidden_dac_lockindex = 5;
  2575. s->cirrus_hidden_dac_data = 0;
  2576. }
  2577. static const MemoryRegionOps cirrus_linear_io_ops = {
  2578. .read = cirrus_linear_read,
  2579. .write = cirrus_linear_write,
  2580. .endianness = DEVICE_LITTLE_ENDIAN,
  2581. .impl = {
  2582. .min_access_size = 1,
  2583. .max_access_size = 1,
  2584. },
  2585. };
  2586. static const MemoryRegionOps cirrus_vga_io_ops = {
  2587. .read = cirrus_vga_ioport_read,
  2588. .write = cirrus_vga_ioport_write,
  2589. .endianness = DEVICE_LITTLE_ENDIAN,
  2590. .impl = {
  2591. .min_access_size = 1,
  2592. .max_access_size = 1,
  2593. },
  2594. };
  2595. void cirrus_init_common(CirrusVGAState *s, Object *owner,
  2596. int device_id, int is_pci,
  2597. MemoryRegion *system_memory, MemoryRegion *system_io)
  2598. {
  2599. int i;
  2600. static int inited;
  2601. if (!inited) {
  2602. inited = 1;
  2603. for(i = 0;i < 256; i++)
  2604. rop_to_index[i] = CIRRUS_ROP_NOP_INDEX; /* nop rop */
  2605. rop_to_index[CIRRUS_ROP_0] = 0;
  2606. rop_to_index[CIRRUS_ROP_SRC_AND_DST] = 1;
  2607. rop_to_index[CIRRUS_ROP_NOP] = 2;
  2608. rop_to_index[CIRRUS_ROP_SRC_AND_NOTDST] = 3;
  2609. rop_to_index[CIRRUS_ROP_NOTDST] = 4;
  2610. rop_to_index[CIRRUS_ROP_SRC] = 5;
  2611. rop_to_index[CIRRUS_ROP_1] = 6;
  2612. rop_to_index[CIRRUS_ROP_NOTSRC_AND_DST] = 7;
  2613. rop_to_index[CIRRUS_ROP_SRC_XOR_DST] = 8;
  2614. rop_to_index[CIRRUS_ROP_SRC_OR_DST] = 9;
  2615. rop_to_index[CIRRUS_ROP_NOTSRC_OR_NOTDST] = 10;
  2616. rop_to_index[CIRRUS_ROP_SRC_NOTXOR_DST] = 11;
  2617. rop_to_index[CIRRUS_ROP_SRC_OR_NOTDST] = 12;
  2618. rop_to_index[CIRRUS_ROP_NOTSRC] = 13;
  2619. rop_to_index[CIRRUS_ROP_NOTSRC_OR_DST] = 14;
  2620. rop_to_index[CIRRUS_ROP_NOTSRC_AND_NOTDST] = 15;
  2621. s->device_id = device_id;
  2622. if (is_pci)
  2623. s->bustype = CIRRUS_BUSTYPE_PCI;
  2624. else
  2625. s->bustype = CIRRUS_BUSTYPE_ISA;
  2626. }
  2627. /* Register ioport 0x3b0 - 0x3df */
  2628. memory_region_init_io(&s->cirrus_vga_io, owner, &cirrus_vga_io_ops, s,
  2629. "cirrus-io", 0x30);
  2630. memory_region_set_flush_coalesced(&s->cirrus_vga_io);
  2631. memory_region_add_subregion(system_io, 0x3b0, &s->cirrus_vga_io);
  2632. memory_region_init(&s->low_mem_container, owner,
  2633. "cirrus-lowmem-container",
  2634. 0x20000);
  2635. memory_region_init_io(&s->low_mem, owner, &cirrus_vga_mem_ops, s,
  2636. "cirrus-low-memory", 0x20000);
  2637. memory_region_add_subregion(&s->low_mem_container, 0, &s->low_mem);
  2638. for (i = 0; i < 2; ++i) {
  2639. static const char *names[] = { "vga.bank0", "vga.bank1" };
  2640. MemoryRegion *bank = &s->cirrus_bank[i];
  2641. memory_region_init_alias(bank, owner, names[i], &s->vga.vram,
  2642. 0, 0x8000);
  2643. memory_region_set_enabled(bank, false);
  2644. memory_region_add_subregion_overlap(&s->low_mem_container, i * 0x8000,
  2645. bank, 1);
  2646. }
  2647. memory_region_add_subregion_overlap(system_memory,
  2648. 0x000a0000,
  2649. &s->low_mem_container,
  2650. 1);
  2651. memory_region_set_coalescing(&s->low_mem);
  2652. /* I/O handler for LFB */
  2653. memory_region_init_io(&s->cirrus_linear_io, owner, &cirrus_linear_io_ops, s,
  2654. "cirrus-linear-io", s->vga.vram_size_mb * MiB);
  2655. memory_region_set_flush_coalesced(&s->cirrus_linear_io);
  2656. /* I/O handler for LFB */
  2657. memory_region_init_io(&s->cirrus_linear_bitblt_io, owner,
  2658. &cirrus_linear_bitblt_io_ops,
  2659. s,
  2660. "cirrus-bitblt-mmio",
  2661. 0x400000);
  2662. memory_region_set_flush_coalesced(&s->cirrus_linear_bitblt_io);
  2663. /* I/O handler for memory-mapped I/O */
  2664. memory_region_init_io(&s->cirrus_mmio_io, owner, &cirrus_mmio_io_ops, s,
  2665. "cirrus-mmio", CIRRUS_PNPMMIO_SIZE);
  2666. memory_region_set_flush_coalesced(&s->cirrus_mmio_io);
  2667. s->real_vram_size =
  2668. (s->device_id == CIRRUS_ID_CLGD5446) ? 4 * MiB : 2 * MiB;
  2669. /* XXX: s->vga.vram_size must be a power of two */
  2670. s->cirrus_addr_mask = s->real_vram_size - 1;
  2671. s->linear_mmio_mask = s->real_vram_size - 256;
  2672. s->vga.get_bpp = cirrus_get_bpp;
  2673. s->vga.get_offsets = cirrus_get_offsets;
  2674. s->vga.get_resolution = cirrus_get_resolution;
  2675. s->vga.cursor_invalidate = cirrus_cursor_invalidate;
  2676. s->vga.cursor_draw_line = cirrus_cursor_draw_line;
  2677. qemu_register_reset(cirrus_reset, s);
  2678. }
  2679. /***************************************
  2680. *
  2681. * PCI bus support
  2682. *
  2683. ***************************************/
  2684. static void pci_cirrus_vga_realize(PCIDevice *dev, Error **errp)
  2685. {
  2686. PCICirrusVGAState *d = PCI_CIRRUS_VGA(dev);
  2687. CirrusVGAState *s = &d->cirrus_vga;
  2688. PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
  2689. int16_t device_id = pc->device_id;
  2690. /*
  2691. * Follow real hardware, cirrus card emulated has 4 MB video memory.
  2692. * Also accept 8 MB/16 MB for backward compatibility.
  2693. */
  2694. if (s->vga.vram_size_mb != 4 && s->vga.vram_size_mb != 8 &&
  2695. s->vga.vram_size_mb != 16) {
  2696. error_setg(errp, "Invalid cirrus_vga ram size '%u'",
  2697. s->vga.vram_size_mb);
  2698. return;
  2699. }
  2700. /* setup VGA */
  2701. if (!vga_common_init(&s->vga, OBJECT(dev), errp)) {
  2702. return;
  2703. }
  2704. cirrus_init_common(s, OBJECT(dev), device_id, 1, pci_address_space(dev),
  2705. pci_address_space_io(dev));
  2706. s->vga.con = graphic_console_init(DEVICE(dev), 0, s->vga.hw_ops, &s->vga);
  2707. /* setup PCI */
  2708. memory_region_init(&s->pci_bar, OBJECT(dev), "cirrus-pci-bar0", 0x2000000);
  2709. /* XXX: add byte swapping apertures */
  2710. memory_region_add_subregion(&s->pci_bar, 0, &s->cirrus_linear_io);
  2711. memory_region_add_subregion(&s->pci_bar, 0x1000000,
  2712. &s->cirrus_linear_bitblt_io);
  2713. /* setup memory space */
  2714. /* memory #0 LFB */
  2715. /* memory #1 memory-mapped I/O */
  2716. /* XXX: s->vga.vram_size must be a power of two */
  2717. pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->pci_bar);
  2718. if (device_id == CIRRUS_ID_CLGD5446) {
  2719. pci_register_bar(&d->dev, 1, 0, &s->cirrus_mmio_io);
  2720. }
  2721. }
  2722. static Property pci_vga_cirrus_properties[] = {
  2723. DEFINE_PROP_UINT32("vgamem_mb", struct PCICirrusVGAState,
  2724. cirrus_vga.vga.vram_size_mb, 4),
  2725. DEFINE_PROP_BOOL("blitter", struct PCICirrusVGAState,
  2726. cirrus_vga.enable_blitter, true),
  2727. DEFINE_PROP_BOOL("global-vmstate", struct PCICirrusVGAState,
  2728. cirrus_vga.vga.global_vmstate, false),
  2729. DEFINE_PROP_END_OF_LIST(),
  2730. };
  2731. static void cirrus_vga_class_init(ObjectClass *klass, void *data)
  2732. {
  2733. DeviceClass *dc = DEVICE_CLASS(klass);
  2734. PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  2735. k->realize = pci_cirrus_vga_realize;
  2736. k->romfile = VGABIOS_CIRRUS_FILENAME;
  2737. k->vendor_id = PCI_VENDOR_ID_CIRRUS;
  2738. k->device_id = CIRRUS_ID_CLGD5446;
  2739. k->class_id = PCI_CLASS_DISPLAY_VGA;
  2740. set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
  2741. dc->desc = "Cirrus CLGD 54xx VGA";
  2742. dc->vmsd = &vmstate_pci_cirrus_vga;
  2743. device_class_set_props(dc, pci_vga_cirrus_properties);
  2744. dc->hotpluggable = false;
  2745. }
  2746. static const TypeInfo cirrus_vga_info = {
  2747. .name = TYPE_PCI_CIRRUS_VGA,
  2748. .parent = TYPE_PCI_DEVICE,
  2749. .instance_size = sizeof(PCICirrusVGAState),
  2750. .class_init = cirrus_vga_class_init,
  2751. .interfaces = (InterfaceInfo[]) {
  2752. { INTERFACE_CONVENTIONAL_PCI_DEVICE },
  2753. { },
  2754. },
  2755. };
  2756. static void cirrus_vga_register_types(void)
  2757. {
  2758. type_register_static(&cirrus_vga_info);
  2759. }
  2760. type_init(cirrus_vga_register_types)