draw_arm.S 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857
  1. /*
  2. * assembly optimized versions of most funtions from draw.c
  3. * (C) notaz, 2006-2010,2017
  4. *
  5. * This work is licensed under the terms of MAME license.
  6. * See COPYING file in the top-level directory.
  7. *
  8. * this is highly specialized, be careful if changing related C code!
  9. */
  10. #include "pico_int_o32.h"
  11. .extern DrawStripInterlace
  12. .equ PDRAW_SPRITES_MOVED, (1<<0)
  13. .equ PDRAW_WND_DIFF_PRIO, (1<<1)
  14. .equ PDRAW_ACC_SPRITES, (1<<2)
  15. .equ PDRAW_DIRTY_SPRITES, (1<<4)
  16. .equ PDRAW_PLANE_HI_PRIO, (1<<6)
  17. .equ PDRAW_SHHI_DONE, (1<<7)
  18. @ helper
  19. .macro TilePixel pat lsrr offs
  20. .if !\lsrr
  21. ands r4, \pat, r2
  22. .else
  23. ands r4, \pat, r2, lsr #\lsrr
  24. .endif
  25. orrne r4, r3, r4
  26. strneb r4, [r1,#\offs]
  27. .endm
  28. @ TileNorm (r1=pdest, r2=pixels8, r3=pal) r4: scratch, pat: register with helper pattern 0xf
  29. .macro TileNorm pat
  30. TilePixel \pat, 12, 0 @ #0x0000f000
  31. TilePixel \pat, 8, 1 @ #0x00000f00
  32. TilePixel \pat, 4, 2 @ #0x000000f0
  33. TilePixel \pat, 0, 3 @ #0x0000000f
  34. TilePixel \pat, 28, 4 @ #0xf0000000
  35. TilePixel \pat, 24, 5 @ #0x0f000000
  36. TilePixel \pat, 20, 6 @ #0x00f00000
  37. TilePixel \pat, 16, 7 @ #0x000f0000
  38. .endm
  39. @ TileFlip (r1=pdest, r2=pixels8, r3=pal) r4: scratch, pat: register with helper pattern 0xf
  40. .macro TileFlip pat
  41. TilePixel \pat, 16, 0 @ #0x000f0000
  42. TilePixel \pat, 20, 1 @ #0x00f00000
  43. TilePixel \pat, 24, 2 @ #0x0f000000
  44. TilePixel \pat, 28, 3 @ #0xf0000000
  45. TilePixel \pat, 0, 4 @ #0x0000000f
  46. TilePixel \pat, 4, 5 @ #0x000000f0
  47. TilePixel \pat, 8, 6 @ #0x00000f00
  48. TilePixel \pat, 12, 7 @ #0x0000f000
  49. .endm
  50. @ shadow/hilight mode
  51. @ this one is for hi priority layer
  52. .macro TilePixelShHP lsrr offs
  53. .if !\lsrr
  54. ands r4, r12, r2
  55. .else
  56. ands r4, r12, r2, lsr #\lsrr
  57. .endif
  58. ldreqb r4, [r1,#\offs]
  59. orrne r4, r3, r4
  60. andeq r4, r4, #0xbf
  61. strb r4, [r1,#\offs]
  62. .endm
  63. @ TileNormShHP (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: register with helper pattern 0xf, touches r3 high bits
  64. .macro TileNormShHP
  65. TilePixelShHP 12, 0 @ #0x0000f000
  66. TilePixelShHP 8, 1 @ #0x00000f00
  67. TilePixelShHP 4, 2 @ #0x000000f0
  68. TilePixelShHP 0, 3 @ #0x0000000f
  69. TilePixelShHP 28, 4 @ #0xf0000000
  70. TilePixelShHP 24, 5 @ #0x0f000000
  71. TilePixelShHP 20, 6 @ #0x00f00000
  72. TilePixelShHP 16, 7 @ #0x000f0000
  73. .endm
  74. @ TileFlipShHP (r1=pdest, r2=pixels8, r3=pal) r4: scratch, pat: register with helper pattern 0xf
  75. .macro TileFlipShHP
  76. TilePixelShHP 16, 0 @ #0x000f0000
  77. TilePixelShHP 20, 1 @ #0x00f00000
  78. TilePixelShHP 24, 2 @ #0x0f000000
  79. TilePixelShHP 28, 3 @ #0xf0000000
  80. TilePixelShHP 0, 4 @ #0x0000000f
  81. TilePixelShHP 4, 5 @ #0x000000f0
  82. TilePixelShHP 8, 6 @ #0x00000f00
  83. TilePixelShHP 12, 7 @ #0x0000f000
  84. .endm
  85. @ TileSingleSh (r1=pdest, r2=pixels8, r3=pal) r4,r7: scratch, r0=sx; r12: helper pattern 0xf
  86. .macro TileSingleSh
  87. tst r0, #1 @ not aligned?
  88. mov r7, #0x00c000
  89. orr r7, r7, #0xc0
  90. ldrneb r4, [r1]
  91. ldreqh r4, [r1]
  92. orr r4, r4, r7
  93. strneb r4, [r1], #1
  94. streqh r4, [r1], #2
  95. ldrh r4, [r1]
  96. orr r4, r4, r7
  97. strh r4, [r1], #2
  98. ldrh r4, [r1]
  99. orr r4, r4, r7
  100. strh r4, [r1], #2
  101. ldrh r4, [r1]
  102. orr r4, r4, r7
  103. strh r4, [r1], #2
  104. ldrneb r4, [r1]
  105. orr r4, r4, r7
  106. strneb r4, [r1], #1
  107. .endm
  108. @ TileSingleHi (r1=pdest, r2=pixels8, r3=pal) r4,r7: scratch, r0=sx, r12: register with helper pattern 0xf
  109. .macro TileSingleHi
  110. tst r1, #1 @ not aligned?
  111. mov r7, #0x008000
  112. orr r7, r7, #0x80
  113. ldrneb r4, [r1], #1
  114. ldreqh r4, [r1], #2 @ 1ci
  115. ldrh r12, [r1], #2
  116. bic r4, r4, r7, lsr #1
  117. orr r4, r4, r7
  118. strneb r4, [r1, #-3]
  119. streqh r4, [r1, #-4]
  120. ldrh r4, [r1], #2
  121. bic r12, r12, r7, lsr #1
  122. orr r12, r12, r7
  123. strh r12, [r1, #-4]
  124. ldrh r12, [r1], #2
  125. bic r4, r4, r7, lsr #1
  126. orr r4, r4, r7
  127. strh r4, [r1, #-4]
  128. ldrneb r4, [r1]
  129. bic r12, r12, r7, lsr #1
  130. orr r12, r12, r7
  131. strh r12, [r1, #-2]
  132. bicne r4, r4, r7, lsr #1
  133. orrne r4, r4, r7
  134. strneb r4, [r1], #1
  135. mov r12, #0xf
  136. .endm
  137. .macro TileDoShGenPixel shift ofs
  138. .if \shift
  139. ands r4, r12, r2, lsr #\shift
  140. .else
  141. ands r4, r12, r2
  142. .endif
  143. beq 0f
  144. cmp r4, #0xe
  145. ldrgeb r7, [r1,#\ofs]
  146. orrlt r7, r3, r4 @ normal
  147. bicge r7, r7, #0xc0
  148. orrge r7, r7, r4, lsl #6
  149. strb r7, [r1,#\ofs]
  150. 0:
  151. .endm
  152. @ TileFlipSh (r1=pdest, r2=pixels8, r3=pal) r4,r7: scratch, r0=sx, r12: register with helper pattern 0xf
  153. .macro TileFlipSh
  154. TileDoShGenPixel 16, 0 @ #0x000f0000
  155. TileDoShGenPixel 20, 1 @ #0x00f00000
  156. TileDoShGenPixel 24, 2 @ #0x0f000000
  157. TileDoShGenPixel 28, 3 @ #0xf0000000
  158. TileDoShGenPixel 0, 4 @ #0x0000000f
  159. TileDoShGenPixel 4, 5 @ #0x000000f0
  160. TileDoShGenPixel 8, 6 @ #0x00000f00
  161. TileDoShGenPixel 12, 7 @ #0x0000f000
  162. .endm
  163. @ TileNormSh (r1=pdest, r2=pixels8, r3=pal) r4,r7: scratch, r0=sx, r12: register with helper pattern 0xf
  164. .macro TileNormSh
  165. TileDoShGenPixel 12, 0 @ #0x0000f000
  166. TileDoShGenPixel 8, 1 @ #0x00000f00
  167. TileDoShGenPixel 4, 2 @ #0x000000f0
  168. TileDoShGenPixel 0, 3 @ #0x0000000f
  169. TileDoShGenPixel 28, 4 @ #0xf0000000
  170. TileDoShGenPixel 24, 5 @ #0x0f000000
  171. TileDoShGenPixel 20, 6 @ #0x00f00000
  172. TileDoShGenPixel 16, 7 @ #0x000f0000
  173. .endm
  174. .macro TileDoShGenPixel_markop shift ofs
  175. .if \shift
  176. ands r4, r12, r2, lsr #\shift
  177. .else
  178. ands r4, r12, r2
  179. .endif
  180. beq 0f
  181. cmp r4, #0xe
  182. ldrgeb r4, [r1,#\ofs]
  183. orrlt r4, r3, r4
  184. orrge r4, r4, #0x80
  185. strb r4, [r1,#\ofs]
  186. 0:
  187. .endm
  188. .macro TileFlipSh_markop
  189. TileDoShGenPixel_markop 16, 0 @ #0x000f0000
  190. TileDoShGenPixel_markop 20, 1 @ #0x00f00000
  191. TileDoShGenPixel_markop 24, 2 @ #0x0f000000
  192. TileDoShGenPixel_markop 28, 3 @ #0xf0000000
  193. TileDoShGenPixel_markop 0, 4 @ #0x0000000f
  194. TileDoShGenPixel_markop 4, 5 @ #0x000000f0
  195. TileDoShGenPixel_markop 8, 6 @ #0x00000f00
  196. TileDoShGenPixel_markop 12, 7 @ #0x0000f000
  197. .endm
  198. .macro TileNormSh_markop
  199. TileDoShGenPixel_markop 12, 0 @ #0x0000f000
  200. TileDoShGenPixel_markop 8, 1 @ #0x00000f00
  201. TileDoShGenPixel_markop 4, 2 @ #0x000000f0
  202. TileDoShGenPixel_markop 0, 3 @ #0x0000000f
  203. TileDoShGenPixel_markop 28, 4 @ #0xf0000000
  204. TileDoShGenPixel_markop 24, 5 @ #0x0f000000
  205. TileDoShGenPixel_markop 20, 6 @ #0x00f00000
  206. TileDoShGenPixel_markop 16, 7 @ #0x000f0000
  207. .endm
  208. .macro TileDoShGenPixel_onlyop_lp shift ofs
  209. .if \shift
  210. ands r7, r12, r2, lsr #\shift
  211. .else
  212. ands r7, r12, r2
  213. .endif
  214. ldrneb r4, [r1,#\ofs]
  215. cmp r7, #0xe
  216. blt 0f
  217. tst r4, #0xc0
  218. bicne r4, r4, #0xc0
  219. orrne r4, r4, r7, lsl #6
  220. strneb r4, [r1,#\ofs]
  221. 0:
  222. .endm
  223. .macro TileFlipSh_onlyop_lp
  224. TileDoShGenPixel_onlyop_lp 16, 0 @ #0x000f0000
  225. TileDoShGenPixel_onlyop_lp 20, 1 @ #0x00f00000
  226. TileDoShGenPixel_onlyop_lp 24, 2 @ #0x0f000000
  227. TileDoShGenPixel_onlyop_lp 28, 3 @ #0xf0000000
  228. TileDoShGenPixel_onlyop_lp 0, 4 @ #0x0000000f
  229. TileDoShGenPixel_onlyop_lp 4, 5 @ #0x000000f0
  230. TileDoShGenPixel_onlyop_lp 8, 6 @ #0x00000f00
  231. TileDoShGenPixel_onlyop_lp 12, 7 @ #0x0000f000
  232. .endm
  233. .macro TileNormSh_onlyop_lp
  234. TileDoShGenPixel_onlyop_lp 12, 0 @ #0x0000f000
  235. TileDoShGenPixel_onlyop_lp 8, 1 @ #0x00000f00
  236. TileDoShGenPixel_onlyop_lp 4, 2 @ #0x000000f0
  237. TileDoShGenPixel_onlyop_lp 0, 3 @ #0x0000000f
  238. TileDoShGenPixel_onlyop_lp 28, 4 @ #0xf0000000
  239. TileDoShGenPixel_onlyop_lp 24, 5 @ #0x0f000000
  240. TileDoShGenPixel_onlyop_lp 20, 6 @ #0x00f00000
  241. TileDoShGenPixel_onlyop_lp 16, 7 @ #0x000f0000
  242. .endm
  243. @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  244. @ struct TileStrip
  245. @ {
  246. @ int nametab; // 0x00
  247. @ int line; // 0x04
  248. @ int hscroll; // 0x08
  249. @ int xmask; // 0x0C
  250. @ int *hc; // 0x10 (pointer to cache buffer)
  251. @ int cells; // 0x14
  252. @ };
  253. @ void DrawLayer(int lflags, int *hcache, int cellskip, int maxcells,
  254. @ struct PicoEState *est)
  255. .global DrawLayer
  256. DrawLayer:
  257. ldr r12, [sp] @ est
  258. stmfd sp!, {r4-r11,lr}
  259. ldr r11, [r12, #OFS_EST_Pico]
  260. mov r8, #1
  261. ldrb r7, [r11, #OFS_Pico_video_reg+16] @ ??vv??hh
  262. mov r6, r1 @ hcache
  263. orr r9, r3, r0, lsl #29 @ r9=force[31]|sh[30]|plane[29]
  264. orr r9, r9, r2, lsl #8 @ |cellskip[15:8]|maxcells[7:0] (tmp)
  265. mov r1, r7, lsl #4
  266. orr r1, r1, #0x00ff
  267. and r10, r7, #3
  268. cmp r10, #1
  269. biclt r1, r1, #0xfc00
  270. biceq r1, r1, #0xfe00
  271. cmp r10, #2
  272. moveq r1, #0x0007
  273. movgt r1, #0x00ff @ r1=ymask=(height<<8)|0xff; ...; // Y Mask in pixels
  274. add r10, r10, #5
  275. cmp r10, #7
  276. subge r10, r10, #1 @ r10=shift[width] (5,6,6,7)
  277. ldr r2, [r12, #OFS_EST_DrawScanline]
  278. ldr lr, [r12, #OFS_EST_PicoMem_vram]
  279. @ Find name table:
  280. ands r0, r0, #1
  281. ldreqb r12, [r11, #OFS_Pico_video_reg+2]
  282. ldrneb r12, [r11, #OFS_Pico_video_reg+4]
  283. @ calculate xmask:
  284. mov r5, r8, lsl r10
  285. sub r5, r5, #1 @ r5=xmask
  286. moveq r12, r12, lsl #10
  287. movne r12, r12, lsl #13
  288. and r12, r12, #(7<<13) @ r12=(ts->nametab<<1) (halfword compliant)
  289. ldrh r8, [r11, #OFS_Pico_video_reg+12]
  290. ldrb r7, [r11, #OFS_Pico_video_reg+11]
  291. mov r4, r8, lsr #8 @ pvid->reg[13]
  292. mov r4, r4, lsl #10 @ htab=pvid->reg[13]<<9; (halfwords)
  293. tst r7, #2
  294. addne r4, r4, r2, lsl #2 @ htab+=DrawScanline<<1; // Offset by line
  295. tst r7, #1
  296. biceq r4, r4, #0x1f @ htab&=~0xf; // Offset by tile
  297. add r4, r4, r0, lsl #1 @ htab+=plane
  298. bic r4, r4, #0x00ff0000 @ just in case
  299. ldrh r3, [lr, r4] @ r3=hscroll
  300. tst r7, #4
  301. bne .DrawStrip_vsscroll
  302. @ Get vertical scroll value:
  303. add r7, lr, #0x012000
  304. add r7, r7, #0x000180 @ r7=PicoMem.vsram (PicoMem+0x22180)
  305. ldr r7, [r7]
  306. tst r8, #2
  307. tstne r8, #4
  308. bne .DrawStrip_interlace
  309. tst r0, r0
  310. movne r7, r7, lsr #16
  311. @ Find the line in the name table
  312. add r2, r2, r7
  313. and r2, r2, r1
  314. mov r4, r2, lsr #3
  315. add r10, r10, #1 @ shift[width]++
  316. add r12, r12, r4, lsl r10 @ nametab+=(ts.line>>3)<<shift[width];
  317. @ ldmia r0, {r1,r2,r3,r5,r6,r9} @ r2=line, r3=ts->hscroll, r5=ts->xmask, r6=ts->hc, r9=ts->cells
  318. and r10,r2, #7
  319. mov r10,r10, lsl #1 @ r10=ty=(ts->line&7)<<1;
  320. orr r10,r10, r9, lsl #24
  321. rsb r8, r3, #0
  322. mov r8, r8, lsr #3 @ r8=tilex=(-ts->hscroll)>>3
  323. sub r1, r3, #1
  324. and r1, r1, #7
  325. add r7, r1, #1 @ r7=dx=((ts->hscroll-1)&7)+1
  326. movs r3, r9, lsl #1 @ (force[31]|sh[30]) << 1
  327. mov r3, #0
  328. orrmi r10,r10, #1<<23 @ r10=cells[31:24]|sh[23]|hi_not_empty[22]
  329. orrcs r10,r10, #1<<20 @ |had_output[21]|force[20]|ty[15:0]
  330. movmi r3, #0x40 @ default to shadowed pal on sh mode
  331. cmp r7, #8
  332. addne r10,r10, #0x01000000 @ we will loop cells+1 times if there is scroll
  333. and r9, r9, #0xff00
  334. add r8, r8, r9, lsr #8 @ tilex+=cellskip
  335. add r7, r7, r9, lsr #5 @ dx+=cellskip<<3;
  336. sub r10,r10,r9, lsl #16 @ cells-=cellskip
  337. @ cache some stuff to avoid mem access
  338. ldr r11,[sp, #9*4] @ est
  339. mov r0, #0xf
  340. ldr r11,[r11, #OFS_EST_HighCol]
  341. mvn r9, #0 @ r9=prevcode=-1
  342. add r1, r11, r7 @ r1=pdest
  343. @ r4 & r7 are scratch in this loop
  344. .dsloop_subr1:
  345. sub r1, r1, #8
  346. .dsloop: @ 40-41 times
  347. subs r10,r10, #0x01000000
  348. bmi .dsloop_exit
  349. .dsloop_enter:
  350. and r7, r5, r8
  351. add r7, lr, r7, lsl #1 @ Pico.vram+((tilex&ts->xmask) as halfwords)
  352. ldrh r7, [r7, r12] @ r7=code (int, but from unsigned, no sign extend)
  353. add r1, r1, #8
  354. add r8, r8, #1
  355. tst r7, #0x8000
  356. tsteq r10, #1<<20 @ force?
  357. bne .DrawStrip_hiprio
  358. cmp r7, r9
  359. beq .DrawStrip_samecode @ we know stuff about this tile already
  360. mov r9, r7 @ remember code
  361. orr r10, r10, #1<<21 @ seen non hi-prio tile
  362. movs r2, r9, lsl #20 @ if (code&0x1000)
  363. mov r2, r2, lsl #1
  364. add r2, r2, r10, lsl #17
  365. mov r2, r2, lsr #17
  366. eorcs r2, r2, #0x0e @ if (code&0x1000) addr^=0xe;
  367. ldr r2, [lr, r2, lsl #1] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels
  368. bic r7, r3, #0x3f
  369. and r3, r9, #0x6000
  370. add r3, r7, r3, lsr #9 @ r3=pal=((code&0x6000)>>9);
  371. .DrawStrip_samecode:
  372. tst r2, r2
  373. beq .dsloop @ tileline blank
  374. cmp r2, r2, ror #4
  375. beq .DrawStrip_SingleColor @ tileline singlecolor
  376. tst r9, #0x0800
  377. bne .DrawStrip_TileFlip
  378. @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r0: helper pattern
  379. .DrawStrip_TileNorm:
  380. TileNorm r0
  381. b .dsloop
  382. .DrawStrip_TileFlip:
  383. TileFlip r0
  384. b .dsloop
  385. .DrawStrip_SingleColor:
  386. and r4, r2, #0xf
  387. orr r4, r3, r4
  388. orr r4, r4, r4, lsl #8
  389. tst r1, #1 @ not aligned?
  390. strneb r4, [r1], #1
  391. streqh r4, [r1], #2
  392. strh r4, [r1], #2
  393. strh r4, [r1], #2
  394. strh r4, [r1], #2
  395. strneb r4, [r1], #1 @ have a remaining unaligned pixel?
  396. b .dsloop_subr1
  397. .DrawStrip_hiprio_maybempt:
  398. cmp r7, r9
  399. beq .dsloop @ must've been empty, otherwise we wouldn't get here
  400. movs r2, r7, lsl #20 @ if (code&0x1000)
  401. mov r2, r2, lsl #1
  402. add r2, r2, r10, lsl #17
  403. mov r2, r2, lsr #17
  404. eorcs r2, r2, #0x0e @ if (code&0x1000) addr^=0xe;
  405. ldr r2, [lr, r2, lsl #1] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels
  406. mov r9, r7 @ remember code
  407. tst r2, r2
  408. beq .dsloop
  409. orr r10, r10, #1<<22
  410. .DrawStrip_hiprio:
  411. tst r10, #0x00d00000 @ sh[23]|hi_not_empty[22]|force[20]
  412. beq .DrawStrip_hiprio_maybempt
  413. sub r0, r1, r11
  414. orr r7, r7, r0, lsl #16
  415. orr r7, r7, r10, lsl #25 @ (ty<<25)
  416. tst r7, #0x1000
  417. eorne r7, r7, #7<<26 @ if(code&0x1000) cval^=7<<26;
  418. str r7, [r6], #4 @ cache hi priority tile
  419. mov r0, #0xf
  420. b .dsloop
  421. .dsloop_exit:
  422. tst r10, #1<<21 @ seen non hi-prio tile
  423. ldr r1, [sp, #9*4] @ est
  424. mov r0, #0
  425. ldreq r2, [r1, #OFS_EST_rendstatus]
  426. str r0, [r6] @ terminate the cache list
  427. orreq r2, r2, #PDRAW_PLANE_HI_PRIO @ had a layer with all hi-prio tiles
  428. streq r2, [r1, #OFS_EST_rendstatus]
  429. ldmfd sp!, {r4-r11,lr}
  430. bx lr
  431. @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  432. .DrawStrip_vsscroll:
  433. rsb r8, r3, #0
  434. mov r8, r8, lsr #3 @ r8=tilex=(-ts->hscroll)>>3
  435. bic r8, r8, #0x3fc00000
  436. orr r8, r8, r5, lsl #25 @ r8=(xmask[31:25]|had_output[24]|tilex[21:0])
  437. ldr r11, [sp, #9*4] @ est
  438. orr r5, r1, r10, lsl #24
  439. ldr r4, [r11, #OFS_EST_DrawScanline]
  440. sub r1, r3, #1
  441. orr r5, r5, r4, lsl #16 @ r5=(shift_width[31:24]|scanline[23:16]|ymask[15:0])
  442. and r1, r1, #7
  443. add r7, r1, #1 @ r7=dx=((ts->hscroll-1)&7)+1
  444. mov r10,r9, lsl #16
  445. tst r0, #1
  446. orrne r10,r10, #0x8000
  447. tst r9, #1<<31
  448. mov r3, #0
  449. orr r10,r10, #0xff000000 @ will be adjusted on entering loop
  450. orrne r10,r10, #1<<23 @ r10=(cell[31:24]|sh[23]|hi_not_empty[22]|cells_max[21:16]|plane[15]|ty[14:0])
  451. movne r3, #0x40 @ default to shadowed pal on sh mode
  452. cmp r7, #8
  453. subne r10,r10, #0x01000000 @ have hscroll, start with negative cell
  454. and r9, r9, #0xff00
  455. add r8, r8, r9, lsr #8 @ tilex+=cellskip
  456. add r7, r7, r9, lsr #5 @ dx+=cellskip<<3;
  457. add r10,r10,r9, lsl #16 @ cell+=cellskip
  458. @ cache some stuff to avoid mem access
  459. ldr r11,[sp, #9*4] @ est
  460. mov r0, #0xf
  461. ldr r11,[r11, #OFS_EST_HighCol]
  462. mvn r9, #0 @ r9=prevcode=-1
  463. add r1, r11, r7 @ r1=pdest
  464. @ r4 & r7 are scratch in this loop
  465. .dsloop_vs_subr1:
  466. sub r1, r1, #8
  467. .dsloop_vs: @ 40-41 times
  468. add r10,r10, #0x01000000
  469. and r4, r10, #0x003f0000
  470. cmp r4, r10, asr #8
  471. ble .dsloop_vs_exit
  472. @ calc offset and read tileline code to r7, also calc ty
  473. add r7, lr, #0x012000
  474. add r7, r7, #0x000180 @ r7=PicoMem.vsram (PicoMem+0x22180)
  475. add r7, r7, r10,asr #23 @ vsram + ((cell&~1)<<1)
  476. bic r7, r7, #3
  477. tst r10,#0x8000 @ plane1?
  478. addne r7, r7, #2
  479. ldrh r7, [r7] @ r7=vscroll
  480. bic r10,r10,#0xff @ clear old ty
  481. and r4, r5, #0xff0000 @ scanline
  482. add r4, r4, r7, lsl #16 @ ... += vscroll
  483. and r4, r4, r5, lsl #16 @ ... &= ymask
  484. and r7, r4, #0x70000
  485. orr r10,r10,r7, lsr #15 @ new ty
  486. mov r4, r4, lsr #19
  487. mov r7, r5, lsr #24
  488. mov r4, r4, lsl r7 @ nametabadd
  489. and r7, r8, r8, lsr #25
  490. add r7, lr, r7, lsl #1 @ PicoMem.vram+((tilex&ts->xmask) as halfwords)
  491. add r7, r7, r4, lsl #1
  492. ldrh r7, [r7, r12] @ r7=code (int, but from unsigned, no sign extend)
  493. add r1, r1, #8
  494. add r8, r8, #1
  495. tst r7, #0x8000
  496. bne .DrawStrip_vs_hiprio
  497. cmp r7, r9
  498. beq .DrawStrip_vs_samecode @ we know stuff about this tile already
  499. mov r9, r7 @ remember code
  500. orr r8, r8, #(1<<24)@ seen non hi-prio tile
  501. movs r2, r9, lsl #20 @ if (code&0x1000)
  502. mov r2, r2, lsl #1
  503. add r2, r2, r10, lsl #17
  504. mov r2, r2, lsr #17
  505. eorcs r2, r2, #0x0e @ if (code&0x1000) addr^=0xe;
  506. ldr r2, [lr, r2, lsl #1] @ pack=*(unsigned int *)(PicoMem.vram+addr); // Get 8 pixels
  507. bic r7, r3, #0x3f
  508. and r3, r9, #0x6000
  509. add r3, r7, r3, lsr #9 @ r3=pal=((code&0x6000)>>9);
  510. .DrawStrip_vs_samecode:
  511. tst r2, r2
  512. beq .dsloop_vs @ tileline blank
  513. cmp r2, r2, ror #4
  514. beq .DrawStrip_vs_SingleColor @ tileline singlecolor
  515. tst r9, #0x0800
  516. bne .DrawStrip_vs_TileFlip
  517. @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r0: helper pattern
  518. .DrawStrip_vs_TileNorm:
  519. TileNorm r0
  520. b .dsloop_vs
  521. .DrawStrip_vs_TileFlip:
  522. TileFlip r0
  523. b .dsloop_vs
  524. .DrawStrip_vs_SingleColor:
  525. and r4, r2, #0xf
  526. orr r4, r3, r4
  527. orr r4, r4, r4, lsl #8
  528. tst r1, #1 @ not aligned?
  529. strneb r4, [r1], #1
  530. streqh r4, [r1], #2
  531. strh r4, [r1], #2
  532. strh r4, [r1], #2
  533. strh r4, [r1], #2
  534. strneb r4, [r1], #1 @ have a remaining unaligned pixel?
  535. b .dsloop_vs_subr1
  536. .DrawStrip_vs_hiprio:
  537. tst r10, #0x00c00000
  538. beq .DrawStrip_vs_hiprio_maybempt
  539. sub r0, r1, r11
  540. orr r7, r7, r0, lsl #16
  541. orr r7, r7, r10, lsl #25 @ (ty<<25)
  542. tst r7, #0x1000
  543. eorne r7, r7, #7<<26 @ if(code&0x1000) cval^=7<<26;
  544. str r7, [r6], #4 @ cache hi priority tile
  545. mov r0, #0xf
  546. b .dsloop_vs
  547. .DrawStrip_vs_hiprio_maybempt:
  548. cmp r7, r9
  549. beq .dsloop_vs @ must've been empty, otherwise we wouldn't get here
  550. movs r2, r7, lsl #20 @ if (code&0x1000)
  551. mov r2, r2, lsl #1
  552. add r2, r2, r10, lsl #17
  553. mov r2, r2, lsr #17
  554. eorcs r2, r2, #0x0e @ if (code&0x1000) addr^=0xe;
  555. ldr r2, [lr, r2, lsl #1] @ pack=*(unsigned int *)(PicoMem.vram+addr); // Get 8 pixels
  556. mov r9, r7 @ remember code
  557. tst r2, r2
  558. orrne r10, r10, #1<<22
  559. bne .DrawStrip_vs_hiprio
  560. b .dsloop_vs
  561. .dsloop_vs_exit:
  562. tst r8, #(1<<24) @ seen non hi-prio tile
  563. ldr r1, [sp, #9*4] @ est
  564. mov r0, #0
  565. ldreq r2, [r1, #OFS_EST_rendstatus]
  566. str r0, [r6] @ terminate the cache list
  567. orreq r2, r2, #PDRAW_PLANE_HI_PRIO @ had a layer with all hi-prio tiles
  568. streq r2, [r1, #OFS_EST_rendstatus]
  569. ldmfd sp!, {r4-r11,lr}
  570. bx lr
  571. @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  572. @ interlace mode 2? Sonic 2?
  573. .DrawStrip_interlace:
  574. tst r0, r0
  575. moveq r7, r7, lsl #21
  576. movne r7, r7, lsl #5
  577. @ Find the line in the name table
  578. add r2, r7, r2, lsl #22 @ r2=(vscroll+(DrawScanline<<1))<<21 (11 bits);
  579. orr r1, r1, #0x80000000
  580. and r2, r2, r1, ror #10 @ &((ymask<<1)|1)<<21;
  581. mov r2, r2, lsr #21
  582. mov r4, r2, lsr #4
  583. mov r12, r12, lsr #1 @ halfwords
  584. add r0, r12, r4, lsl r10 @ nametab+=(ts.line>>4)<<shift[width];
  585. and r9, r9, #0xff
  586. sub sp, sp, #6*4
  587. stmia sp, {r0,r2,r3,r5,r6,r9}
  588. mov r0, sp
  589. bl DrawStripInterlace @ struct TileStrip *ts
  590. add sp, sp, #6*4
  591. ldmfd sp!, {r4-r11,lr}
  592. bx lr
  593. .pool
  594. @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  595. @ void BackFill(int reg7, int sh, struct PicoEState *est)
  596. .global BackFill
  597. BackFill:
  598. stmfd sp!, {r4-r9,lr}
  599. mov r0, r0, lsl #26
  600. ldr lr, [r2, #OFS_EST_HighCol]
  601. mov r0, r0, lsr #26
  602. add lr, lr, #8
  603. orr r0, r0, r1, lsl #6
  604. orr r0, r0, r0, lsl #8
  605. orr r0, r0, r0, lsl #16
  606. mov r1, r0
  607. mov r2, r0
  608. mov r3, r0
  609. mov r4, r0
  610. mov r5, r0
  611. mov r6, r0
  612. mov r7, r0
  613. @ go go go!
  614. stmia lr!, {r0-r7} @ 10*8*4
  615. stmia lr!, {r0-r7}
  616. stmia lr!, {r0-r7}
  617. stmia lr!, {r0-r7}
  618. stmia lr!, {r0-r7}
  619. stmia lr!, {r0-r7}
  620. stmia lr!, {r0-r7}
  621. stmia lr!, {r0-r7}
  622. stmia lr!, {r0-r7}
  623. stmia lr!, {r0-r7}
  624. ldmfd sp!, {r4-r9,lr}
  625. bx lr
  626. @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  627. @ void DrawTilesFromCache(int *hc, int sh, int rlim, struct PicoEState *est)
  628. .global DrawTilesFromCache
  629. DrawTilesFromCache:
  630. stmfd sp!, {r4-r9,r11,lr}
  631. @ cache some stuff to avoid mem access
  632. ldr r11,[r3, #OFS_EST_HighCol]
  633. mov r12,#0xf
  634. ldr lr, [r3, #OFS_EST_PicoMem_vram]
  635. mov r9, r3 @ est
  636. mvn r5, #0 @ r5=prevcode=-1
  637. ands r8, r1, #1
  638. orr r8, r8, r2, lsl #1
  639. bne .dtfc_check_rendflags
  640. @ scratch: r4, r7
  641. .dtfc_loop:
  642. ldr r6, [r0], #4 @ read code
  643. movs r1, r6, lsr #16 @ r1=dx;
  644. ldmeqfd sp!, {r4-r9,r11,pc} @ dx is never zero, this must be a terminator, return
  645. bic r4, r1, #0xfe00
  646. add r1, r11, r4 @ r1=pdest
  647. movs r7, r6, lsl #16
  648. bpl .dtfc_loop @ !(code & 0x8000)
  649. cmp r5, r7, lsr #16
  650. beq .dtfc_samecode @ if (code==prevcode)
  651. mov r5, r7, lsr #16
  652. mov r2, r5, lsl #21
  653. mov r2, r2, lsr #17 @ r2=addr=(code&0x7ff)<<4;
  654. add r2, r2, r6, lsr #25 @ addr+=ty
  655. and r3, r5, #0x6000
  656. mov r3, r3, lsr #9 @ r3=pal=((code&0x6000)>>9);
  657. ldr r2, [lr, r2, lsl #1] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels
  658. .dtfc_samecode:
  659. rsbs r4, r4, r8, lsr #1
  660. bmi .dtfc_cut_tile
  661. tst r8, #1
  662. bne .dtfc_shadow
  663. tst r2, r2
  664. beq .dtfc_loop
  665. cmp r2, r2, ror #4
  666. beq .dtfc_SingleColor @ tileline singlecolor
  667. tst r5, #0x0800
  668. bne .dtfc_TileFlip
  669. @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern
  670. .dtfc_TileNorm:
  671. TileNorm r12
  672. b .dtfc_loop
  673. .dtfc_TileFlip:
  674. TileFlip r12
  675. b .dtfc_loop
  676. .dtfc_SingleColor:
  677. and r4, r2, #0xf
  678. orr r4, r3, r4
  679. orr r4, r4, r4, lsl #8
  680. tst r1, #1 @ not aligned?
  681. strneb r4, [r1], #1
  682. streqh r4, [r1], #2
  683. strh r4, [r1], #2
  684. strh r4, [r1], #2
  685. strh r4, [r1], #2
  686. strneb r4, [r1], #1 @ have a remaining unaligned pixel?
  687. b .dtfc_loop
  688. .dtfc_shadow:
  689. tst r2, r2
  690. beq .dtfc_shadow_blank
  691. cmp r2, r2, ror #4
  692. beq .dtfc_SingleColor @ tileline singlecolor
  693. tst r5, #0x0800
  694. bne .dtfc_TileFlipShHP
  695. @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern
  696. .dtfc_TileNormShHP:
  697. TileNormShHP
  698. b .dtfc_loop
  699. .dtfc_TileFlipShHP:
  700. TileFlipShHP
  701. b .dtfc_loop
  702. .dtfc_shadow_blank:
  703. tst r1, #1
  704. ldrneb r4, [r1]
  705. mov r6, #0xbf
  706. and r4, r4, #0xbf
  707. strneb r4, [r1], #1
  708. ldrh r4, [r1]
  709. orr r6, r6, r6, lsl #8
  710. and r4, r4, r6
  711. strh r4, [r1], #2
  712. ldrh r4, [r1]
  713. and r4, r4, r6
  714. strh r4, [r1], #2
  715. ldrh r4, [r1]
  716. and r4, r4, r6
  717. strh r4, [r1], #2
  718. ldrh r4, [r1]
  719. and r4, r4, r6
  720. streqh r4, [r1]
  721. strneb r4, [r1]
  722. b .dtfc_loop
  723. .dtfc_cut_tile:
  724. add r4, r4, #7 @ 0-6
  725. mov r4, r4, lsl #2
  726. mov r12,#0xf<<28
  727. mov r12,r12,asr r4
  728. mov r2, r2, ror #16
  729. tst r5, #0x0800 @ flipped?
  730. mvnne r12,r12
  731. and r2, r2, r12
  732. mov r2, r2, ror #16
  733. mov r12,#0xf
  734. tst r8, #1
  735. bne .dtfc_shadow
  736. tst r2, r2
  737. beq .dtfc_loop
  738. tst r5, #0x0800
  739. beq .dtfc_TileNorm
  740. b .dtfc_TileFlip
  741. @ check if we have detected layer covered with hi-prio tiles:
  742. .dtfc_check_rendflags:
  743. ldr r2, [r9, #OFS_EST_rendstatus]
  744. tst r2, #(PDRAW_PLANE_HI_PRIO|PDRAW_SHHI_DONE)
  745. beq .dtfc_loop
  746. bic r8, r8, #1 @ sh/hi mode off
  747. tst r2, #PDRAW_SHHI_DONE
  748. bne .dtfc_loop @ already processed
  749. orr r2, r2, #PDRAW_SHHI_DONE
  750. str r2, [r9, #OFS_EST_rendstatus]
  751. add r1, r11,#8
  752. mov r3, #320/4/4
  753. mov r6, #0xbf
  754. orr r6, r6, r6, lsl #8
  755. orr r6, r6, r6, lsl #16
  756. .dtfc_loop_shprep:
  757. ldmia r1, {r2,r4,r5,r7}
  758. subs r3, r3, #1
  759. and r2, r2, r6
  760. and r4, r4, r6
  761. and r5, r5, r6
  762. and r7, r7, r6
  763. stmia r1!,{r2,r4,r5,r7}
  764. bne .dtfc_loop_shprep
  765. mvn r5, #0 @ r5=prevcode=-1
  766. b .dtfc_loop
  767. .pool
  768. @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  769. @ void DrawSpritesSHi(unsigned char *sprited, struct PicoEState *est)
  770. .global DrawSpritesSHi
  771. DrawSpritesSHi:
  772. ldr r3, [r0]
  773. mov r12,#0xff
  774. ands r3, r3, #0x7f
  775. bxeq lr
  776. stmfd sp!, {r1,r4-r11,lr} @ +est
  777. strb r12,[r0,#2] @ set end marker
  778. add r10,r0, #3 @ r10=HighLnSpr end
  779. add r10,r10,r3 @ r10=HighLnSpr end
  780. ldr r11,[r1, #OFS_EST_HighCol]
  781. mov r12,#0xf
  782. ldr lr, [r1, #OFS_EST_PicoMem_vram]
  783. DrawSpriteSHi:
  784. @ draw next sprite
  785. ldrb r0, [r10,#-1]!
  786. ldr r7, [sp] @ est
  787. ldr r1, [r7, #OFS_EST_HighPreSpr]
  788. cmp r0, #0xff
  789. ldmeqfd sp!, {r1,r4-r11,pc} @ end of list
  790. and r0, r0, #0x7f
  791. add r0, r1, r0, lsl #3
  792. ldr r9, [r0, #4] @ sprite[1]
  793. mov r2, r9, asr #16 @ r2=sx
  794. mov r9, r9, lsl #16
  795. mov r3, r9, lsr #31 @ priority
  796. mov r9, r9, lsr #16
  797. @ orr r9, r9, r8, lsl #31 @ r9=code|sh[31] @@ sh is always on here now
  798. and r4, r9, #0x6000
  799. orr r9, r9, r4, lsl #16
  800. orr r9, r9, #0x90000000 @ r9=scc1 ???? ... <code> (s=shadow/hilight, cc=pal)
  801. cmp r12,r9, lsr #28 @ sh/hi with pal3?
  802. cmpne r3, #1 @ if not, is it hi prio?
  803. bne DrawSpriteSHi @ non-operator low sprite, already drawn
  804. ldr r3, [r0] @ sprite[0]
  805. mov r6, r3, lsr #28
  806. sub r6, r6, #1 @ r6=width-1 (inc later)
  807. mov r5, r3, lsr #24
  808. and r5, r5, #7 @ r5=height
  809. ldr r7, [r7, #OFS_EST_DrawScanline]
  810. mov r0, r3, lsl #16 @ r4=sy<<16 (tmp)
  811. sub r7, r7, r0, asr #16 @ r7=row=DrawScanline-sy
  812. tst r9, #0x1000
  813. movne r0, r5, lsl #3
  814. subne r0, r0, #1
  815. subne r7, r0, r7 @ if (code&0x1000) row=(height<<3)-1-row; // Flip Y
  816. add r8, r9, r7, lsr #3 @ tile+=row>>3; // Tile number increases going down
  817. tst r9, #0x0800
  818. mlane r8, r5, r6, r8 @ if (code&0x0800) { tile+=delta*(width-1);
  819. rsbne r5, r5, #0 @ delta=-delta; } // r5=delta now
  820. mov r8, r8, lsl #21
  821. mov r8, r8, lsr #17
  822. and r7, r7, #7
  823. add r8, r8, r7, lsl #1 @ tile+=(row&7)<<1; // Tile address
  824. mov r5, r5, lsl #4 @ delta<<=4; // Delta of address
  825. mov r3, r4, lsr #9 @ r3=pal=((code>>9)&0x30);
  826. add r6, r6, #1 @ inc now
  827. adds r0, r2, #0 @ mov sx to r0 and set ZV flags
  828. b .dsprShi_loop_enter
  829. .dsprShi_loop:
  830. subs r6, r6, #1 @ width--
  831. beq DrawSpriteSHi
  832. adds r0, r0, #8 @ sx+=8
  833. add r8, r8, r5 @ tile+=delta
  834. .dsprShi_loop_enter:
  835. ble .dsprShi_loop @ sx <= 0
  836. cmp r0, #328
  837. bge DrawSpriteSHi
  838. mov r8, r8, lsl #17
  839. mov r8, r8, lsr #17 @ tile&=0x7fff; // Clip tile address
  840. ldr r2, [lr, r8, lsl #1] @ pack=*(unsigned int *)(PicoMem.vram+addr); // Get 8 pixels
  841. add r1, r11, r0 @ r1=pdest
  842. tst r2, r2
  843. beq .dsprShi_loop
  844. cmp r12, r9, lsr #28
  845. beq .dsprShi_shadow
  846. cmp r2, r2, ror #4
  847. beq .dsprShi_SingleColor @ tileline singlecolor
  848. tst r9, #0x0800
  849. bne .dsprShi_TileFlip
  850. @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern
  851. @ scratch: r4, r7
  852. .dsprShi_TileNorm:
  853. TileNorm r12
  854. b .dsprShi_loop
  855. .dsprShi_TileFlip:
  856. TileFlip r12
  857. b .dsprShi_loop
  858. .dsprShi_SingleColor:
  859. and r4, r2, #0xf
  860. orr r4, r3, r4
  861. orr r4, r4, r4, lsl #8
  862. tst r0, #1 @ not aligned?
  863. strneb r4, [r1], #1
  864. streqh r4, [r1], #2
  865. strh r4, [r1], #2
  866. strh r4, [r1], #2
  867. strh r4, [r1], #2
  868. strneb r4, [r1], #1
  869. b .dsprShi_loop
  870. .dsprShi_shadow:
  871. tst r9, #0x8000
  872. beq .dsprShi_shadow_lowpri
  873. cmp r2, r2, ror #4
  874. beq .dsprShi_singlec_sh
  875. tst r9, #0x0800
  876. bne .dsprShi_TileFlip_sh
  877. @ (r1=pdest, r2=pixels8, r3=pal) r4, r7: scratch, r12: helper pattern
  878. .dsprShi_TileNorm_sh:
  879. TileNormSh
  880. b .dsprShi_loop
  881. .dsprShi_TileFlip_sh:
  882. TileFlipSh
  883. b .dsprShi_loop
  884. .dsprShi_singlec_sh:
  885. cmp r2, #0xe0000000
  886. bcc .dsprShi_SingleColor @ normal singlecolor tileline (carry inverted in ARM)
  887. tst r2, #0x10000000
  888. bne .dsprShi_sh_sh
  889. TileSingleHi
  890. b .dsprShi_loop
  891. .dsprShi_sh_sh:
  892. TileSingleSh
  893. b .dsprShi_loop
  894. .dsprShi_shadow_lowpri:
  895. tst r9, #0x800
  896. bne .dsprShi_TileFlip_sh_lp
  897. .dsprShi_TileNorm_sh_lp:
  898. TileNormSh_onlyop_lp
  899. b .dsprShi_loop
  900. .dsprShi_TileFlip_sh_lp:
  901. TileFlipSh_onlyop_lp
  902. b .dsprShi_loop
  903. .pool
  904. @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  905. @ void DrawAllSprites(unsigned char *sprited, int prio, int sh,
  906. @ struct PicoEState *est)
  907. .global DrawAllSprites
  908. DrawAllSprites:
  909. orr r1, r2, r1, lsl #1
  910. ldr r2, [r0]
  911. ands r2, r2, #0x7f
  912. bxeq lr
  913. @ time to do some real work
  914. stmfd sp!, {r1,r3-r11,lr} @ +sh|prio<<1 +est
  915. mov r12,#0xff
  916. strb r12,[r0,#2] @ set end marker
  917. add r10,r0, #3
  918. add r10,r10,r2 @ r10=HighLnSpr end
  919. ldr r11,[r3, #OFS_EST_HighCol]
  920. mov r12,#0xf
  921. ldr lr, [r3, #OFS_EST_PicoMem_vram]
  922. @ + 0 : hhhhvvvv ----hhvv yyyyyyyy yyyyyyyy // v, h: horiz. size
  923. @ + 4 : xxxxxxxx xxxxxxxx pccvhnnn nnnnnnnn // x: x coord + 8
  924. DrawSprite:
  925. @ draw next sprite
  926. ldrb r0, [r10,#-1]!
  927. ldr r8, [sp] @ sh|prio<<1
  928. ldr r7, [sp, #4] @ est
  929. mov r2, r0, lsr #7
  930. cmp r0, #0xff
  931. ldmeqfd sp!, {r1,r3-r11,pc} @ end of list
  932. cmp r2, r8, lsr #1
  933. bne DrawSprite @ wrong priority
  934. ldr r1, [r7, #OFS_EST_HighPreSpr]
  935. and r0, r0, #0x7f
  936. add r0, r1, r0, lsl #3
  937. ldr r3, [r0] @ sprite[0]
  938. ldr r7, [r7, #OFS_EST_DrawScanline]
  939. mov r6, r3, lsr #28
  940. sub r6, r6, #1 @ r6=width-1 (inc later)
  941. mov r5, r3, lsr #24
  942. and r5, r5, #7 @ r5=height
  943. mov r4, r3, lsl #16 @ r4=sy<<16 (tmp)
  944. ldr r9, [r0, #4]
  945. sub r7, r7, r4, asr #16 @ r7=row=DrawScanline-sy
  946. mov r2, r9, asr #16 @ r2=sx
  947. mov r9, r9, lsl #16
  948. mov r9, r9, lsr #16
  949. orr r9, r9, r8, lsl #31 @ r9=code|sh[31]
  950. tst r9, #0x1000
  951. movne r4, r5, lsl #3
  952. subne r4, r4, #1
  953. subne r7, r4, r7 @ if (code&0x1000) row=(height<<3)-1-row; // Flip Y
  954. add r8, r9, r7, lsr #3 @ tile+=row>>3; // Tile number increases going down
  955. tst r9, #0x0800
  956. mlane r8, r5, r6, r8 @ if (code&0x0800) { tile+=delta*(width-1);
  957. rsbne r5, r5, #0 @ delta=-delta; } // r5=delta now
  958. mov r8, r8, lsl #21
  959. mov r8, r8, lsr #17
  960. and r7, r7, #7
  961. add r8, r8, r7, lsl #1 @ tile+=(row&7)<<1; // Tile address
  962. .dspr_continue:
  963. @ cache some stuff to avoid mem access
  964. mov r5, r5, lsl #4 @ delta<<=4; // Delta of address
  965. and r4, r9, #0x6000
  966. orr r9, r9, r4, lsl #16
  967. orrs r9, r9, #0x10000000 @ r9=scc1 ???? ... <code> (s=shadow/hilight, cc=pal)
  968. mov r3, r4, lsr #9 @ r3=pal=((code>>9)&0x30);
  969. orrmi r3, r3, #0x40 @ for sh/hi
  970. add r6, r6, #1 @ inc now
  971. adds r0, r2, #0 @ mov sx to r0 and set ZV flags
  972. b .dspr_loop_enter
  973. .dspr_loop:
  974. subs r6, r6, #1 @ width--
  975. beq DrawSprite
  976. adds r0, r0, #8 @ sx+=8
  977. add r8, r8, r5 @ tile+=delta
  978. .dspr_loop_enter:
  979. ble .dspr_loop @ sx <= 0
  980. cmp r0, #328
  981. bge DrawSprite
  982. mov r8, r8, lsl #17
  983. mov r8, r8, lsr #17 @ tile&=0x7fff; // Clip tile address
  984. ldr r2, [lr, r8, lsl #1] @ pack=*(unsigned int *)(PicoMem.vram+addr); // Get 8 pixels
  985. add r1, r11, r0 @ r1=pdest
  986. tst r2, r2
  987. beq .dspr_loop
  988. cmp r12, r9, lsr #28
  989. beq .dspr_shadow
  990. cmp r2, r2, ror #4
  991. beq .dspr_SingleColor @ tileline singlecolor
  992. tst r9, #0x0800
  993. bne .dspr_TileFlip
  994. @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern
  995. @ scratch: r4, r7
  996. .dspr_TileNorm:
  997. TileNorm r12
  998. b .dspr_loop
  999. .dspr_TileFlip:
  1000. TileFlip r12
  1001. b .dspr_loop
  1002. .dspr_singlec_sh:
  1003. cmp r2, #0xe0000000
  1004. bcs .dspr_TileNorm_sh @ op. tileline, markop. XXX: maybe add a spec. handler?
  1005. .dspr_SingleColor:
  1006. and r4, r2, #0xf
  1007. orr r4, r3, r4
  1008. orr r4, r4, r4, lsl #8
  1009. tst r0, #1 @ not aligned?
  1010. strneb r4, [r1], #1
  1011. streqh r4, [r1], #2
  1012. strh r4, [r1], #2
  1013. strh r4, [r1], #2
  1014. strh r4, [r1], #2
  1015. strneb r4, [r1], #1
  1016. b .dspr_loop
  1017. .dspr_shadow:
  1018. cmp r2, r2, ror #4
  1019. beq .dspr_singlec_sh
  1020. tst r9, #0x0800
  1021. bne .dspr_TileFlip_sh
  1022. @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern
  1023. .dspr_TileNorm_sh:
  1024. TileNormSh_markop
  1025. b .dspr_loop
  1026. .dspr_TileFlip_sh:
  1027. TileFlipSh_markop
  1028. b .dspr_loop
  1029. @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  1030. @ void DrawWindow(int tstart, int tend, int prio, int sh
  1031. @ struct PicoEState *est)
  1032. .global DrawWindow
  1033. DrawWindow:
  1034. ldr r12, [sp] @ est
  1035. stmfd sp!, {r4-r11,lr}
  1036. ldr r6, [r12, #OFS_EST_Pico]
  1037. ldr r10, [r12, #OFS_EST_DrawScanline]
  1038. mov r11, r12 @ est
  1039. ldrb r12, [r6, #OFS_Pico_video_reg+3] @ pvid->reg[3]
  1040. ldr r4, [r6, #OFS_Pico_video_reg+12]
  1041. mov r5, r10, lsr #3
  1042. and r10, r10, #7
  1043. mov r10, r10, lsl #1 @ r10=ty
  1044. mov r12, r12, lsl #10
  1045. tst r4, #1 @ 40 cell mode?
  1046. andne r12, r12, #0xf000 @ 0x3c<<10
  1047. andeq r12, r12, #0xf800
  1048. addne r12, r12, r5, lsl #7
  1049. addeq r12, r12, r5, lsl #6 @ nametab
  1050. add r12, r12, r0, lsl #2 @ +starttile
  1051. ldr lr, [r11, #OFS_EST_PicoMem_vram]
  1052. ldr r6, [r11, #OFS_EST_rendstatus]
  1053. @ fetch the first code now
  1054. ldrh r7, [lr, r12]
  1055. ands r6, r6, #PDRAW_WND_DIFF_PRIO
  1056. orr r6, r6, r2
  1057. eoreq r8, r2, r7, lsr #15 @ do prio bits differ?
  1058. cmpeq r8, #1
  1059. ldmeqfd sp!, {r4-r11,pc} @ yes, assume that whole window uses same priority
  1060. orr r6, r6, r3, lsl #8 @ shadow mode
  1061. sub r8, r1, r0
  1062. @ cache some stuff to avoid mem access
  1063. ldr r11, [r11, #OFS_EST_HighCol]
  1064. mov r8, r8, lsl #1 @ cells
  1065. add r11,r11,#8
  1066. mvn r9, #0 @ r9=prevcode=-1
  1067. add r1, r11, r0, lsl #4 @ r1=pdest
  1068. mov r0, #0xf
  1069. b .dwloop_enter
  1070. @ r4,r5 are scratch in this loop
  1071. .dwloop:
  1072. add r1, r1, #8
  1073. .dwloop_nor1:
  1074. add r12, r12, #2 @ halfwords
  1075. ldrh r7, [lr, r12] @ r7=code (int, but from unsigned, no sign extend)
  1076. subs r8, r8, #1
  1077. beq .dwloop_end @ done
  1078. eor r5, r6, r7, lsr #15
  1079. tst r5, #1
  1080. orrne r6, r6, #2 @ wrong pri
  1081. bne .dwloop
  1082. cmp r7, r9
  1083. beq .dw_samecode @ we know stuff about this tile already
  1084. .dwloop_enter:
  1085. mov r9, r7 @ remember code
  1086. movs r2, r9, lsl #20 @ if (code&0x1000)
  1087. mov r2, r2, lsl #1
  1088. add r2, r10, r2, lsr #17 @ r2=addr=(code&0x7ff)<<4; addr+=ty
  1089. eorcs r2, r2, #0x0e @ if (code&0x1000) addr^=0xe;
  1090. and r3, r9, #0x6000
  1091. mov r3, r3, lsr #9 @ r3=pal=((code&0x6000)>>9);
  1092. ldr r2, [lr, r2, lsl #1] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels
  1093. .dw_samecode:
  1094. tst r6, #0x100
  1095. bne .dw_shadow
  1096. .dw_shadow_done:
  1097. tst r2, r2
  1098. beq .dwloop @ tileline blank
  1099. cmp r2, r2, ror #4
  1100. beq .dw_SingleColor @ tileline singlecolor
  1101. tst r9, #0x0800
  1102. bne .dw_TileFlip
  1103. @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r0: helper pattern
  1104. .dw_TileNorm:
  1105. TileNorm r0
  1106. b .dwloop
  1107. .dw_TileFlip:
  1108. TileFlip r0
  1109. b .dwloop
  1110. .dw_SingleColor:
  1111. and r4, r0, r2 @ #0x0000000f
  1112. orr r4, r3, r4
  1113. orr r4, r4, r4, lsl #8
  1114. orr r4, r4, r4, lsl #16
  1115. mov r5, r4
  1116. stmia r1!, {r4,r5}
  1117. b .dwloop_nor1 @ we incremeted r1 ourselves
  1118. .dw_shadow:
  1119. tst r6, #1 @ hi pri?
  1120. orreq r3, r3, #0x40
  1121. beq .dw_shadow_done
  1122. ldr r4, [r1]
  1123. mov r5, #0x3f
  1124. orr r5, r5, r5, lsl #8
  1125. orr r5, r5, r5, lsl #16
  1126. and r4, r4, r5
  1127. str r4, [r1]
  1128. ldr r4, [r1,#4]
  1129. and r4, r4, r5
  1130. str r4, [r1,#4]
  1131. b .dw_shadow_done
  1132. .dwloop_end:
  1133. and r2, r6, #PDRAW_WND_DIFF_PRIO
  1134. ldmfd sp!, {r4-r11,lr}
  1135. ldr r0, [sp]
  1136. ldr r1, [r0, #OFS_EST_rendstatus]
  1137. orr r1, r1, r2
  1138. str r1, [r0, #OFS_EST_rendstatus]
  1139. bx lr
  1140. @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  1141. @ hilights 2 pixels in RGB444/BGR444 format
  1142. .macro TileDoShHi2Pixels444 reg
  1143. mov \reg, \reg, ror #12
  1144. adds \reg, \reg, #0x40000000
  1145. orrcs \reg, \reg, #0xf0000000
  1146. mov \reg, \reg, ror #28
  1147. adds \reg, \reg, #0x40000000
  1148. orrcs \reg, \reg, #0xf0000000
  1149. mov \reg, \reg, ror #28
  1150. adds \reg, \reg, #0x40000000
  1151. orrcs \reg, \reg, #0xf0000000
  1152. mov \reg, \reg, ror #24
  1153. adds \reg, \reg, #0x40000000
  1154. orrcs \reg, \reg, #0xf0000000
  1155. mov \reg, \reg, ror #28
  1156. adds \reg, \reg, #0x40000000
  1157. orrcs \reg, \reg, #0xf0000000
  1158. mov \reg, \reg, ror #28
  1159. adds \reg, \reg, #0x40000000
  1160. orrcs \reg, \reg, #0xf0000000
  1161. mov \reg, \reg, ror #12
  1162. .endm
  1163. @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  1164. @ Convert 0000bbb0 ggg0rrr0
  1165. @ to rrrrrggg gggbbbbb
  1166. @ r2,r3 - scratch, lr = 0x001c001c, r8 = 0x08610861
  1167. .macro convRGB565 reg
  1168. and r2, lr, \reg,lsr #7 @ b
  1169. and r3, lr, \reg,lsr #3 @ g
  1170. and \reg, lr, \reg,lsl #1 @ r
  1171. orr r2, r2, r3, lsl #6
  1172. orr \reg, r2, \reg,lsl #11
  1173. and r2, r8, \reg,lsr #4
  1174. orr \reg, \reg, r2
  1175. .endm
  1176. @ trashes: r2-r8,r12,lr; r8 = 0x08610861; r0,r1 are advanced
  1177. .macro vidConvCpyRGB565_local
  1178. mov r12, r2, lsr #3 @ repeats
  1179. mov lr, #0x001c0000
  1180. orr lr, lr, #0x01c @ lr == pattern 0x001c001c
  1181. 0:
  1182. ldmia r1!, {r4-r7}
  1183. subs r12, r12, #1
  1184. convRGB565 r4
  1185. str r4, [r0], #4
  1186. convRGB565 r5
  1187. str r5, [r0], #4
  1188. convRGB565 r6
  1189. str r6, [r0], #4
  1190. convRGB565 r7
  1191. str r7, [r0], #4
  1192. bgt 0b
  1193. .endm
  1194. .global vidConvCpyRGB565
  1195. vidConvCpyRGB565: @ void *to, void *from, int pixels
  1196. stmfd sp!, {r4-r9,lr}
  1197. mov r8, #0x0061
  1198. orr r8, r8, #0x0800
  1199. orr r8, r8, r8, lsl #16
  1200. vidConvCpyRGB565_local
  1201. ldmfd sp!, {r4-r9,lr}
  1202. bx lr
  1203. @ void PicoDoHighPal555(int sh, int line, struct PicoEState *est)
  1204. .global PicoDoHighPal555
  1205. PicoDoHighPal555:
  1206. stmfd sp!, {r4-r10,lr}
  1207. mov r10,r2 @ est
  1208. mov r1, #0
  1209. ldr r8, [r10, #OFS_EST_Pico]
  1210. PicoDoHighPal555_nopush:
  1211. orr r9, r1, r0, lsl #31 @ 0:called from FinalizeLine555, 31: s/h
  1212. add r0, r10, #OFS_EST_HighPal
  1213. mov r1, #0
  1214. strb r1, [r8, #OFS_Pico_m_dirtyPal]
  1215. ldr r1, [r10, #OFS_EST_PicoMem_cram]
  1216. mov r2, #0x40
  1217. mov r8, #0x0061
  1218. orr r8, r8, #0x0800
  1219. orr r8, r8, r8, lsl #16
  1220. vidConvCpyRGB565_local
  1221. tst r9, #(1<<31)
  1222. beq PicoDoHighPal555_end
  1223. add r3, r10, #OFS_EST_HighPal
  1224. @ shadowed pixels:
  1225. mov r12, #0x008e
  1226. add r4, r3, #0x40*2
  1227. orr r12,r12,#0x7300
  1228. add r5, r3, #0xc0*2
  1229. orr r12,r12,r12,lsl #16
  1230. mov lr, #0x40/4
  1231. .fl_loopcpRGB555_sh:
  1232. ldmia r3!, {r1,r6}
  1233. subs lr, lr, #1
  1234. and r1, r12, r1, lsr #1
  1235. and r6, r12, r6, lsr #1
  1236. stmia r4!, {r1,r6}
  1237. stmia r5!, {r1,r6}
  1238. bne .fl_loopcpRGB555_sh
  1239. @ hilighted pixels:
  1240. @ t = ((dpal[i] >> 1) & 0x738e738e) + 0x738e738e;
  1241. @ t |= (t >> 4) & 0x08610861;
  1242. @ r8=0x08610861
  1243. sub r3, r3, #0x40*2
  1244. mov lr, #0x40/4
  1245. .fl_loopcpRGB555_hi:
  1246. ldmia r3!, {r1,r6}
  1247. and r1, r12, r1, lsr #1
  1248. and r6, r12, r6, lsr #1
  1249. add r1, r12, r1
  1250. add r6, r12, r6
  1251. and r5, r8, r1, lsr #4
  1252. and r7, r8, r6, lsr #4
  1253. orr r1, r1, r5
  1254. orr r6, r6, r7
  1255. stmia r4!, {r1,r6}
  1256. subs lr, lr, #1
  1257. bne .fl_loopcpRGB555_hi
  1258. mov r0, #1
  1259. PicoDoHighPal555_end:
  1260. tst r9, #1
  1261. ldmeqfd sp!, {r4-r10,pc}
  1262. ldr r8, [r10, #OFS_EST_Pico]
  1263. b FinalizeLineRGB555_pal_done
  1264. @ void FinalizeLine555(int sh, int line, struct PicoEState *est)
  1265. .global FinalizeLine555
  1266. FinalizeLine555:
  1267. stmfd sp!, {r4-r10,lr}
  1268. mov r10,r2 @ est
  1269. ldr r8, [r10, #OFS_EST_Pico]
  1270. ldrb r2, [r8, #OFS_Pico_m_dirtyPal]
  1271. mov r1, #1
  1272. tst r2, r2
  1273. bne PicoDoHighPal555_nopush
  1274. FinalizeLineRGB555_pal_done:
  1275. add r3, r10, #OFS_EST_HighPal
  1276. ldr r12, [r10, #OFS_EST_rendstatus]
  1277. eors r0, r0, #1 @ sh is 0
  1278. mov lr, #0xff
  1279. tstne r12,#PDRAW_ACC_SPRITES
  1280. movne lr, #0x3f
  1281. ldr r1, [r10, #OFS_EST_HighCol]
  1282. ldr r0, [r10, #OFS_EST_DrawLineDest]
  1283. add r1, r1, #8
  1284. ldrb r12, [r8, #OFS_Pico_video_reg+12]
  1285. mov lr, lr, lsl #1
  1286. tst r12, #1
  1287. movne r2, #320/8 @ len
  1288. bne .fl_no32colRGB555
  1289. ldr r4, [r10, #OFS_EST_PicoOpt]
  1290. mov r2, #256/8
  1291. ldr r4, [r4]
  1292. tst r4, #0x4000
  1293. bne .fl_32scale_RGB555
  1294. tst r4, #0x0100
  1295. addeq r0, r0, #32*2
  1296. .fl_no32colRGB555:
  1297. #ifdef UNALIGNED_DRAWLINEDEST
  1298. @ this is basically for Gizmondo, which has unaligned odd lines in the framebuffer
  1299. tst r0, #2
  1300. bne .fl_RGB555u
  1301. #endif
  1302. .fl_loopRGB555:
  1303. ldr r12, [r1], #4
  1304. ldr r7, [r1], #4
  1305. and r4, lr, r12, lsl #1
  1306. ldrh r4, [r3, r4]
  1307. and r5, lr, r12, lsr #7
  1308. ldrh r5, [r3, r5]
  1309. and r6, lr, r12, lsr #15
  1310. ldrh r6, [r3, r6]
  1311. orr r4, r4, r5, lsl #16
  1312. and r5, lr, r12, lsr #23
  1313. ldrh r5, [r3, r5]
  1314. and r8, lr, r7, lsl #1
  1315. ldrh r8, [r3, r8]
  1316. orr r5, r6, r5, lsl #16
  1317. and r6, lr, r7, lsr #7
  1318. ldrh r6, [r3, r6]
  1319. and r12,lr, r7, lsr #15
  1320. ldrh r12,[r3, r12]
  1321. and r7, lr, r7, lsr #23
  1322. ldrh r7, [r3, r7]
  1323. orr r8, r8, r6, lsl #16
  1324. subs r2, r2, #1
  1325. orr r12,r12, r7, lsl #16
  1326. stmia r0!, {r4,r5,r8,r12}
  1327. bne .fl_loopRGB555
  1328. ldmfd sp!, {r4-r10,lr}
  1329. bx lr
  1330. .fl_32scale_RGB555:
  1331. mov r9, #0x3900 @ f800 07e0 001f | e000 0780 001c | 3800 01e0 0007
  1332. orr r9, r9, #0x00e7
  1333. #ifdef UNALIGNED_DRAWLINEDEST
  1334. tst r0, #2
  1335. bne .fl_32scale_RGB555u
  1336. #endif
  1337. .fl_loop32scale_RGB555:
  1338. ldr r12, [r1], #4
  1339. ldr r7, [r1], #4
  1340. and r4, lr, r12,lsl #1
  1341. ldrh r4, [r3, r4]
  1342. and r5, lr, r12,lsr #7
  1343. ldrh r5, [r3, r5]
  1344. and r4, r4, r9, lsl #2
  1345. orr r4, r4, r4, lsl #14 @ r4[31:16] = 1/4 pix_s 0
  1346. and r5, r5, r9, lsl #2
  1347. sub r6, r5, r5, lsr #2 @ r6 = 3/4 pix_s 1
  1348. add r4, r4, r6, lsl #16 @ pix_d 0, 1
  1349. and r6, lr, r12,lsr #15
  1350. ldrh r6, [r3, r6]
  1351. and r12,lr, r12,lsr #23
  1352. ldrh r12,[r3, r12]
  1353. and r6, r6, r9, lsl #2
  1354. add r5, r5, r6
  1355. mov r5, r5, lsr #1
  1356. sub r6, r6, r6, lsr #2 @ r6 = 3/4 pix_s 2
  1357. orr r5, r5, r6, lsl #16
  1358. and r6, lr, r7, lsl #1
  1359. ldrh r6, [r3, r6]
  1360. and r12,r12,r9, lsl #2
  1361. add r5, r5, r12,lsl #14 @ pix_d 2, 3
  1362. and r6, r6, r9, lsl #2
  1363. orr r6, r12,r6, lsl #16 @ pix_d 4, 5
  1364. and r12,lr, r7, lsr #7
  1365. ldrh r12,[r3, r12]
  1366. and r10,lr, r7, lsr #15
  1367. ldrh r10,[r3, r10]
  1368. and r12,r12,r9, lsl #2
  1369. sub r8, r12,r12,lsr #2 @ r8 = 3/4 pix_s 1
  1370. add r8, r8, r6, lsr #18
  1371. and r7, lr, r7, lsr #23
  1372. ldrh r7, [r3, r7]
  1373. and r10,r10,r9, lsl #2
  1374. orr r8, r8, r10,lsl #15
  1375. add r8, r8, r12,lsl #15 @ pix_d 6, 7
  1376. sub r10,r10,r10,lsr #2 @ r10= 3/4 pix_s 2
  1377. and r7, r7, r9, lsl #2
  1378. add r10,r10,r7, lsr #2 @ += 1/4 pix_s 3
  1379. orr r10,r10,r7, lsl #16 @ pix_d 8, 9
  1380. subs r2, r2, #1
  1381. stmia r0!, {r4,r5,r6,r8,r10}
  1382. bne .fl_loop32scale_RGB555
  1383. ldmfd sp!, {r4-r10,lr}
  1384. bx lr
  1385. #ifdef UNALIGNED_DRAWLINEDEST
  1386. @ unaligned versions of loops
  1387. @ warning: starts drawing 2bytes before dst
  1388. .fl_RGB555u:
  1389. sub r0, r0, #2 @ initial adjustment
  1390. mov r8, #0
  1391. .fl_loopRGB555u:
  1392. ldr r12, [r1], #4
  1393. ldr r7, [r1], #4
  1394. and r6, lr, r12,lsl #1
  1395. ldrh r6, [r3, r6]
  1396. and r5, lr, r12,lsr #7
  1397. ldrh r5, [r3, r5]
  1398. orr r4, r8, r6, lsl #16
  1399. and r6, lr, r12,lsr #15
  1400. ldrh r6, [r3, r6]
  1401. and r8, lr, r12,lsr #23
  1402. ldrh r8, [r3, r8]
  1403. orr r5, r5, r6, lsl #16
  1404. and r6, lr, r7, lsl #1
  1405. ldrh r6, [r3, r6]
  1406. and r12,lr, r7, lsr #7
  1407. ldrh r12,[r3, r12]
  1408. orr r6, r8, r6, lsl #16
  1409. and r8, lr, r7, lsr #15
  1410. ldrh r8, [r3, r8]
  1411. and r7, lr, r7, lsr #23
  1412. subs r2, r2, #1
  1413. orr r12,r12,r8, lsl #16
  1414. ldrh r8, [r3, r7]
  1415. stmia r0!, {r4,r5,r6,r12}
  1416. bne .fl_loopRGB555u
  1417. strh r8, [r0], #2
  1418. ldmfd sp!, {r4-r10,lr}
  1419. bx lr
  1420. .fl_32scale_RGB555u:
  1421. sub r0, r0, #2 @ initial adjustment
  1422. mov r4, #0
  1423. @ r9 f800 07e0 001f | e000 0780 001c | 3800 01e0 0007
  1424. .fl_loop32scale_RGB555u:
  1425. ldr r12, [r1], #4
  1426. ldr r7, [r1], #4
  1427. and r6, lr, r12,lsl #1
  1428. ldrh r6, [r3, r6]
  1429. and r5, lr, r12,lsr #7
  1430. ldrh r5, [r3, r5]
  1431. and r6, r6, r9, lsl #2
  1432. orr r4, r4, r6, lsl #16 @ r4 = pix_d -1, 0
  1433. and r5, r5, r9, lsl #2
  1434. sub r8, r5, r5, lsr #2 @ r8 = 3/4 pix_s 1
  1435. add r6, r8, r6, lsr #2 @ r6 = (1/4 pix_s 0) + (3/4 pix_s 1)
  1436. orr r5, r6, r5, lsl #15
  1437. and r6, lr, r12,lsr #15
  1438. ldrh r6, [r3, r6]
  1439. and r12,lr, r12,lsr #23
  1440. ldrh r12,[r3, r12]
  1441. and r6, r6, r9, lsl #2
  1442. add r5, r5, r6, lsl #15 @ r5 = pix_d 1, 2
  1443. and r8, lr, r7, lsl #1
  1444. ldrh r8, [r3, r8]
  1445. and r10,lr, r7, lsr #7
  1446. ldrh r10,[r3, r10]
  1447. and r12,r12,r9, lsl #2
  1448. sub r6, r6, r6, lsr #2 @ r6 = 3/4 pix_s 2
  1449. add r6, r6, r12,lsr #2
  1450. orr r6, r6, r12,lsl #16 @ r6 = pix_d 3, 4
  1451. and r8, r8, r9, lsl #2
  1452. and r10,r10,r9, lsl #2
  1453. sub r12,r10,r10,lsr #2 @ r12 = 3/4 pix_s 5
  1454. orr r8, r8, r8, lsl #14
  1455. add r8, r8, r12,lsl #16 @ r8 = pix_d 5, 6
  1456. and r12,lr, r7, lsr #15
  1457. ldrh r12,[r3, r12]
  1458. and r7, lr, r7, lsr #23
  1459. ldrh r7, [r3, r7]
  1460. and r12,r12,r9, lsl #2
  1461. add r10,r10,r12
  1462. mov r10,r10, lsr #1
  1463. sub r12,r12,r12,lsr #2 @ r12 = 3/4 pix_s 6
  1464. orr r10,r10,r12,lsl #16
  1465. and r7, r7, r9, lsl #2
  1466. add r10,r10,r7, lsl #14 @ r10 = pix_d 7, 8
  1467. subs r2, r2, #1
  1468. stmia r0!, {r4,r5,r6,r8,r10}
  1469. mov r4, r7
  1470. bne .fl_loop32scale_RGB555u
  1471. strh r4, [r0], #2
  1472. ldmfd sp!, {r4-r10,lr}
  1473. bx lr
  1474. #endif /* UNALIGNED_DRAWLINEDEST */
  1475. @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  1476. @ utility
  1477. .global blockcpy @ void *dst, void *src, size_t n
  1478. blockcpy:
  1479. stmfd sp!, {r4,r5}
  1480. mov r2, r2, lsr #4
  1481. blockcpy_loop:
  1482. ldmia r1!, {r3-r5,r12}
  1483. subs r2, r2, #1
  1484. stmia r0!, {r3-r5,r12}
  1485. bne blockcpy_loop
  1486. ldmfd sp!, {r4,r5}
  1487. bx lr
  1488. .global blockcpy_or @ void *dst, void *src, size_t n, int pat
  1489. blockcpy_or:
  1490. stmfd sp!, {r4-r6}
  1491. orr r3, r3, r3, lsl #8
  1492. orr r3, r3, r3, lsl #16
  1493. mov r2, r2, lsr #4
  1494. blockcpy_loop_or:
  1495. ldmia r1!, {r4-r6,r12}
  1496. subs r2, r2, #1
  1497. orr r4, r4, r3
  1498. orr r5, r5, r3
  1499. orr r6, r6, r3
  1500. orr r12,r12,r3
  1501. stmia r0!, {r4-r6,r12}
  1502. bne blockcpy_loop_or
  1503. ldmfd sp!, {r4-r6}
  1504. bx lr
  1505. @ vim:filetype=armasm