draw_arm.s 55 KB

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