Draw.s 55 KB

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