draw2_arm.S 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941
  1. /*
  2. * assembly optimized versions of most funtions from draw2.c
  3. * (C) notaz, 2006-2008
  4. *
  5. * This work is licensed under the terms of MAME license.
  6. * See COPYING file in the top-level directory.
  7. *
  8. * this is highly specialized, be careful if changing related C code!
  9. */
  10. #include "pico_int_o32.h"
  11. @ define these constants in your include file:
  12. @ .equiv START_ROW, 1
  13. @ .equiv END_ROW, 27
  14. @ one row means 8 pixels. If above example was used, (27-1)*8=208 lines would be rendered.
  15. #ifndef START_ROW
  16. #define START_ROW 0
  17. #endif
  18. #ifndef END_ROW
  19. #define END_ROW 28
  20. #endif
  21. .text
  22. .align 2
  23. @ void BackFillFull(void *dst, int reg7)
  24. .global BackFillFull
  25. BackFillFull:
  26. stmfd sp!, {r4-r9,lr}
  27. add lr, r0, #328*8
  28. mov r0, r1, lsl #26
  29. mov r0, r0, lsr #26
  30. orr r0, r0, r0, lsl #8
  31. orr r0, r0, r0, lsl #16
  32. mov r1, r0 @ 25 opcodes wasted?
  33. mov r2, r0
  34. mov r3, r0
  35. mov r4, r0
  36. mov r5, r0
  37. mov r6, r0
  38. mov r7, r0
  39. mov r8, r0
  40. mov r9, r0
  41. mov r12, #(END_ROW-START_ROW)*8
  42. @ go go go!
  43. .bff_loop:
  44. add lr, lr, #8
  45. subs r12, r12, #1
  46. stmia lr!, {r0-r9} @ 10*4*8
  47. stmia lr!, {r0-r9}
  48. stmia lr!, {r0-r9}
  49. stmia lr!, {r0-r9}
  50. stmia lr!, {r0-r9}
  51. stmia lr!, {r0-r9}
  52. stmia lr!, {r0-r9}
  53. stmia lr!, {r0-r9}
  54. bne .bff_loop
  55. ldmfd sp!, {r4-r9,lr}
  56. bx lr
  57. .pool
  58. @ -------- some macros --------
  59. @ helper
  60. @ TileLineSinglecol (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r0: pixels8_old
  61. .macro TileLineSinglecol notsinglecol=0
  62. and r2, r2, #0xf @ #0x0000000f
  63. .if !\notsinglecol
  64. cmp r2, r0, lsr #28 @ if these don't match,
  65. bicne r9, r9, #2 @ it is a sign that whole tile is not singlecolor (only it's lines may be)
  66. .endif
  67. orr r4, r3, r2
  68. orr r4, r4, r4, lsl #8
  69. tst r1, #1 @ not aligned?
  70. strneb r4, [r1], #1
  71. streqh r4, [r1], #2
  72. strh r4, [r1], #2
  73. strh r4, [r1], #2
  74. strh r4, [r1], #2
  75. strneb r4, [r1], #1 @ have a remaining unaligned pixel?
  76. sub r1, r1, #8
  77. .if !\notsinglecol
  78. mov r0, #0xf
  79. orr r0, r0, r2, lsl #28 @ we will need the old palindex later
  80. .endif
  81. .endm
  82. @ TileNorm (r1=pdest, r2=pixels8, r3=pal) r0,r4: scratch
  83. .macro TileLineNorm
  84. ands r4, r0, r2, lsr #12 @ #0x0000f000
  85. orrne r4, r3, r4
  86. strneb r4, [r1]
  87. ands r4, r0, r2, lsr #8 @ #0x00000f00
  88. orrne r4, r3, r4
  89. strneb r4, [r1,#1]
  90. ands r4, r0, r2, lsr #4 @ #0x000000f0
  91. orrne r4, r3, r4
  92. strneb r4, [r1,#2]
  93. ands r4, r0, r2 @ #0x0000000f
  94. orrne r4, r3, r4
  95. strneb r4, [r1,#3]
  96. ands r4, r0, r2, lsr #28 @ #0xf0000000
  97. orrne r4, r3, r4
  98. strneb r4, [r1,#4]
  99. ands r4, r0, r2, lsr #24 @ #0x0f000000
  100. orrne r4, r3, r4
  101. strneb r4, [r1,#5]
  102. ands r4, r0, r2, lsr #20 @ #0x00f00000
  103. orrne r4, r3, r4
  104. strneb r4, [r1,#6]
  105. ands r4, r0, r2, lsr #16 @ #0x000f0000
  106. orrne r4, r3, r4
  107. strneb r4, [r1,#7]
  108. .endm
  109. @ TileFlip (r1=pdest, r2=pixels8, r3=pal) r0,r4: scratch
  110. .macro TileLineFlip
  111. ands r4, r0, r2, lsr #16 @ #0x000f0000
  112. orrne r4, r3, r4
  113. strneb r4, [r1]
  114. ands r4, r0, r2, lsr #20 @ #0x00f00000
  115. orrne r4, r3, r4
  116. strneb r4, [r1,#1]
  117. ands r4, r0, r2, lsr #24 @ #0x0f000000
  118. orrne r4, r3, r4
  119. strneb r4, [r1,#2]
  120. ands r4, r0, r2, lsr #28 @ #0xf0000000
  121. orrne r4, r3, r4
  122. strneb r4, [r1,#3]
  123. ands r4, r0, r2 @ #0x0000000f
  124. orrne r4, r3, r4
  125. strneb r4, [r1,#4]
  126. ands r4, r0, r2, lsr #4 @ #0x000000f0
  127. orrne r4, r3, r4
  128. strneb r4, [r1,#5]
  129. ands r4, r0, r2, lsr #8 @ #0x00000f00
  130. orrne r4, r3, r4
  131. strneb r4, [r1,#6]
  132. ands r4, r0, r2, lsr #12 @ #0x0000f000
  133. orrne r4, r3, r4
  134. strneb r4, [r1,#7]
  135. .endm
  136. @ Tile (r1=pdest, r3=pal, r9=prevcode, r10=Pico.vram) r2,r4,r7: scratch, r0=0xf
  137. .macro Tile hflip vflip
  138. mov r7, r9, lsl #13 @ r9=code<<8; addr=(code&0x7ff)<<4;
  139. add r7, r10, r7, lsr #16
  140. orr r9, r9, #3 @ emptytile=singlecolor=1, r9 must be <code_16> 00000xxx
  141. .if \vflip
  142. @ we read tilecodes in reverse order if we have vflip
  143. add r7, r7, #8*4
  144. .endif
  145. @ loop through 8 lines
  146. orr r9, r9, #(7<<24)
  147. b 1f @ loop_enter
  148. 0: @ singlecol_loop
  149. subs r9, r9, #(1<<24)
  150. add r1, r1, #328 @ set pointer to next line
  151. bmi 8f @ loop_exit with r0 restore
  152. 1:
  153. .if \vflip
  154. ldr r2, [r7, #-4]! @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels
  155. .else
  156. ldr r2, [r7], #4
  157. .endif
  158. tst r2, r2
  159. beq 2f @ empty line
  160. bic r9, r9, #1
  161. cmp r2, r2, ror #4
  162. bne 3f @ not singlecolor
  163. TileLineSinglecol
  164. b 0b
  165. 2:
  166. bic r9, r9, #2
  167. 2: @ empty_loop
  168. subs r9, r9, #(1<<24)
  169. add r1, r1, #328 @ set pointer to next line
  170. bmi 8f @ loop_exit with r0 restore
  171. .if \vflip
  172. ldr r2, [r7, #-4]! @ next pack
  173. .else
  174. ldr r2, [r7], #4
  175. .endif
  176. mov r0, #0xf @ singlecol_loop might have messed r0
  177. tst r2, r2
  178. beq 2b
  179. bic r9, r9, #3 @ if we are here, it means we have empty and not empty line
  180. b 5f
  181. 3: @ not empty, not singlecol
  182. mov r0, #0xf
  183. bic r9, r9, #3
  184. b 6f
  185. 4: @ not empty, not singlecol loop
  186. subs r9, r9, #(1<<24)
  187. add r1, r1, #328 @ set pointer to next line
  188. bmi 9f @ loop_exit
  189. .if \vflip
  190. ldr r2, [r7, #-4]! @ next pack
  191. .else
  192. ldr r2, [r7], #4
  193. .endif
  194. tst r2, r2
  195. beq 4b @ empty line
  196. 5:
  197. cmp r2, r2, ror #4
  198. beq 7f @ singlecolor line
  199. 6:
  200. .if \hflip
  201. TileLineFlip
  202. .else
  203. TileLineNorm
  204. .endif
  205. b 4b
  206. 7:
  207. TileLineSinglecol 1
  208. b 4b
  209. 8:
  210. mov r0, #0xf
  211. 9: @ loop_exit
  212. add r9, r9, #(1<<24) @ fix r9
  213. sub r1, r1, #328*8 @ restore pdest pointer
  214. .endm
  215. @ TileLineSinglecolAl (r1=pdest, r4,r7=color)
  216. .macro TileLineSinglecolAl0
  217. stmia r1!, {r4,r7}
  218. add r1, r1, #320
  219. .endm
  220. .macro TileLineSinglecolAl1
  221. strb r4, [r1], #1
  222. strh r4, [r1], #2
  223. str r4, [r1], #4
  224. strb r4, [r1], #1+320
  225. @ add r1, r1, #320
  226. .endm
  227. .macro TileLineSinglecolAl2
  228. strh r4, [r1], #2
  229. str r4, [r1], #4
  230. strh r4, [r1], #2
  231. add r1, r1, #320
  232. .endm
  233. .macro TileLineSinglecolAl3
  234. strb r4, [r1], #1
  235. str r4, [r1], #4
  236. strh r4, [r1], #2
  237. strb r4, [r1], #1+320
  238. @ add r1, r1, #320
  239. .endm
  240. @ TileSinglecol (r1=pdest, r2=pixels8, r3=pal) r4,r7: scratch, r0=0xf
  241. @ kaligned==1, if dest is always aligned
  242. .macro TileSinglecol kaligned=0
  243. and r4, r2, #0xf @ we assume we have good r2 from previous time
  244. orr r4, r4, r3
  245. orr r4, r4, r4, lsl #8
  246. orr r4, r4, r4, lsl #16
  247. mov r7, r4
  248. .if !\kaligned
  249. tst r1, #2 @ not aligned?
  250. bne 2f
  251. tst r1, #1
  252. bne 1f
  253. .endif
  254. TileLineSinglecolAl0
  255. TileLineSinglecolAl0
  256. TileLineSinglecolAl0
  257. TileLineSinglecolAl0
  258. TileLineSinglecolAl0
  259. TileLineSinglecolAl0
  260. TileLineSinglecolAl0
  261. TileLineSinglecolAl0
  262. .if !\kaligned
  263. b 4f
  264. 1:
  265. TileLineSinglecolAl1
  266. TileLineSinglecolAl1
  267. TileLineSinglecolAl1
  268. TileLineSinglecolAl1
  269. TileLineSinglecolAl1
  270. TileLineSinglecolAl1
  271. TileLineSinglecolAl1
  272. TileLineSinglecolAl1
  273. b 4f
  274. 2:
  275. tst r1, #1
  276. bne 3f
  277. TileLineSinglecolAl2
  278. TileLineSinglecolAl2
  279. TileLineSinglecolAl2
  280. TileLineSinglecolAl2
  281. TileLineSinglecolAl2
  282. TileLineSinglecolAl2
  283. TileLineSinglecolAl2
  284. TileLineSinglecolAl2
  285. b 4f
  286. 3:
  287. TileLineSinglecolAl3
  288. TileLineSinglecolAl3
  289. TileLineSinglecolAl3
  290. TileLineSinglecolAl3
  291. TileLineSinglecolAl3
  292. TileLineSinglecolAl3
  293. TileLineSinglecolAl3
  294. TileLineSinglecolAl3
  295. 4:
  296. .endif
  297. sub r1, r1, #328*8 @ restore pdest pointer
  298. .endm
  299. @ DrawLayerTiles(*hcache, *scrpos, (cells<<24)|(nametab<<9)|(vscroll&0x3ff)<<11|(shift[width]<<8)|planeend, (ymask<<24)|(planestart<<16)|[htab||hscroll]
  300. @ void DrawLayerFull(int plane, int *hcache, int planestart, int planeend,
  301. @ struct PicoEState *est)
  302. .global DrawLayerFull
  303. DrawLayerFull:
  304. ldr r12,[sp] @ est
  305. stmfd sp!, {r4-r11,lr}
  306. mov r6, r1 @ hcache
  307. ldr r11, [r12, #OFS_EST_Pico]
  308. ldr r10, [r12, #OFS_EST_PicoMem_vram]
  309. ldrb r5, [r11, #OFS_Pico_video_reg+13] @ pvid->reg[13]
  310. ldrb r7, [r11, #OFS_Pico_video_reg+11]
  311. sub lr, r3, r2
  312. and lr, lr, #0x00ff0000 @ lr=cells
  313. mov r5, r5, lsl #10 @ htab=pvid->reg[13]<<9; (halfwords)
  314. add r5, r5, r0, lsl #1 @ htab+=plane
  315. bic r5, r5, #0x00ff0000 @ just in case
  316. tst r7, #3 @ full screen scroll? (if ==0)
  317. ldrb r7, [r11, #OFS_Pico_video_reg+16] @ ??hh??ww
  318. ldreqh r5, [r10, r5]
  319. biceq r5, r5, #0x0000fc00 @ r5=hscroll (0-0x3ff)
  320. movne r5, r5, lsr #1
  321. orrne r5, r5, #0x8000 @ this marks that we have htab pointer, not hscroll here
  322. and r8, r7, #3
  323. orr r5, r5, r7, lsl #1+24
  324. orr r5, r5, #0x1f000000
  325. cmp r8, #1
  326. biclt r5, r5, #0x80000000
  327. biceq r5, r5, #0xc0000000
  328. bicgt r5, r5, #0xe0000000
  329. mov r9, r2, lsl #24
  330. orr r5, r5, r9, lsr #8 @ r5=(ymask<<24)|(trow<<16)|[htab||hscroll]
  331. add r4, r8, #5
  332. cmp r4, #7
  333. subge r4, r4, #1 @ r4=shift[width] (5,6,6,7)
  334. orr lr, lr, r4
  335. orr lr, lr, r3, lsl #24 @ lr=(planeend<<24)|(cells<<16)|shift[width]
  336. @ calculate xmask:
  337. mov r8, r8, lsl #24+5
  338. orr r8, r8, #0x1f000000
  339. @ Find name table:
  340. tst r0, r0
  341. ldreqb r4, [r11, #OFS_Pico_video_reg+2]
  342. moveq r4, r4, lsr #3
  343. ldrneb r4, [r11, #OFS_Pico_video_reg+4]
  344. and r4, r4, #7
  345. orr lr, lr, r4, lsl #13 @ lr|=nametab_bits{3}<<13
  346. ldr r11,[sp, #9*4] @ est
  347. sub r4, r9, #(START_ROW<<24)
  348. ldr r11, [r11, #OFS_EST_Draw2FB]
  349. mov r4, r4, asr #24
  350. mov r7, #328*8
  351. mla r11, r4, r7, r11 @ scrpos+=8*328*(planestart-START_ROW);
  352. @ Get vertical scroll value:
  353. add r7, r10, #0x012000
  354. add r7, r7, #0x000180 @ r7=Pico.vsram (Pico+0x22180)
  355. ldr r7, [r7]
  356. tst r0, r0
  357. moveq r7, r7, lsl #22
  358. movne r7, r7, lsl #6
  359. mov r7, r7, lsr #22 @ r7=vscroll (10 bits)
  360. orr lr, lr, r7, lsl #3
  361. mov lr, lr, ror #24 @ packed: cccccccc nnnvvvvv vvvvvsss pppppppp: cells, nametab, vscroll, shift[width], planeend
  362. ands r7, r7, #7
  363. addne lr, lr, #1 @ we have vertically clipped tiles due to vscroll, so we need 1 more row
  364. rsb r7, r7, #8
  365. str r7, [r6], #4 @ push y-offset to tilecache
  366. mov r4, #328
  367. mla r11, r4, r7, r11 @ scrpos+=(8-(vscroll&7))*328;
  368. mov r9, #0xff000000 @ r9=(prevcode<<8)|flags: 1~tile empty, 2~tile singlecolor
  369. .rtrloop_outer:
  370. mov r4, lr, lsl #11
  371. mov r4, r4, lsr #25 @ r4=vscroll>>3 (7 bits)
  372. add r4, r4, r5, lsr #16 @ +trow
  373. and r4, r4, r5, lsr #24 @ &=ymask
  374. mov r7, lr, lsr #8
  375. and r7, r7, #7 @ shift[width]
  376. mov r0, lr, lsr #9
  377. and r0, r0, #0x7000 @ nametab
  378. add r12,r0, r4, lsl r7 @ nametab_row = nametab + (((trow+(vscroll>>3))&ymask)<<shift[width]);
  379. mov r4, lr, lsr #24
  380. orr r12,r12,r4, lsl #23
  381. mov r12,r12,lsl #1 @ (nametab_row|(cells<<24)) (halfword compliant)
  382. @ htab?
  383. tst r5, #0x8000
  384. moveq r7, r5, lsl #22 @ hscroll (0-3FFh)
  385. moveq r7, r7, lsr #22
  386. beq .rtr_hscroll_done
  387. @ get hscroll from htab
  388. mov r7, r5, lsl #17
  389. ands r4, r5, #0x00ff0000
  390. add r7, r7, r4, lsl #5 @ +=trow<<4
  391. andne r4, lr, #0x3800
  392. subne r7, r7, r4, lsl #7 @ if(trow) htaddr-=(vscroll&7)<<1;
  393. mov r7, r7, lsr #16 @ halfwords
  394. ldrh r7, [r10, r7]
  395. .rtr_hscroll_done:
  396. and r8, r8, #0xff000000
  397. rsb r4, r7, #0 @ r4=tilex=(-ts->hscroll)>>3
  398. mov r4, r4, asr #3
  399. and r4, r4, #0xff
  400. orr r8, r8, r4 @ r8=(xmask<<24)|tilex
  401. sub r7, r7, #1
  402. and r7, r7, #7
  403. add r7, r7, #1 @ r7=dx=((ts->hscroll-1)&7)+1
  404. cmp r7, #8
  405. subeq r12,r12, #0x01000000 @ we will loop cells+1 times, so loop less when there is no hscroll
  406. add r1, r11, r7 @ r1=pdest
  407. mov r0, #0xf
  408. b .rtrloop_enter
  409. @ r4 & r7 are scratch in this loop
  410. .rtrloop: @ 40-41 times
  411. add r1, r1, #8
  412. subs r12,r12, #0x01000000
  413. add r8, r8, #1
  414. bmi .rtrloop_exit
  415. .rtrloop_enter:
  416. and r7, r8, r8, lsr #24
  417. add r7, r10, r7, lsl #1
  418. bic r4, r12, #0xff000000 @ Pico.vram[nametab_row+(tilex&xmask)];
  419. ldrh r7, [r7, r4] @ r7=code (int, but from unsigned, no sign extend)
  420. tst r7, #0x8000
  421. bne .rtr_hiprio
  422. cmp r7, r9, lsr #8
  423. bne .rtr_notsamecode
  424. @ we know stuff about this tile already
  425. tst r9, #1
  426. bne .rtrloop @ empty tile
  427. tst r9, #2
  428. bne .rtr_singlecolor @ singlecolor tile
  429. b .rtr_samecode
  430. .rtr_notsamecode:
  431. and r4, r9, #0x600000
  432. mov r9, r7, lsl #8 @ remember new code
  433. @ update cram
  434. and r7, r7, #0x6000
  435. mov r3, r7, asr #9 @ r3=pal=((code&0x6000)>>9);
  436. .rtr_samecode:
  437. tst r9, #0x100000 @ vflip?
  438. bne .rtr_vflip
  439. tst r9, #0x080000 @ hflip?
  440. bne .rtr_hflip
  441. @ Tile (r1=pdest, r3=pal, r9=prevcode, r10=Pico.vram) r2,r4,r7: scratch, r0=0xf
  442. Tile 0, 0
  443. b .rtrloop
  444. .rtr_hflip:
  445. Tile 1, 0
  446. b .rtrloop
  447. .rtr_vflip:
  448. tst r9, #0x080000 @ hflip?
  449. bne .rtr_vflip_hflip
  450. Tile 0, 1
  451. b .rtrloop
  452. .rtr_vflip_hflip:
  453. Tile 1, 1
  454. b .rtrloop
  455. .rtr_singlecolor:
  456. TileSinglecol
  457. b .rtrloop
  458. .rtr_hiprio:
  459. @ *(*hcache)++ = code|(dx<<16)|(trow<<27);
  460. sub r4, r1, r11
  461. orr r7, r7, r4, lsl #16
  462. and r4, r5, #0x00ff0000
  463. orr r7, r7, r4, lsl #11 @ (trow<<27)
  464. str r7, [r6], #4 @ cache hi priority tile
  465. b .rtrloop
  466. .rtrloop_exit:
  467. add r5, r5, #0x00010000
  468. mov r4, r5, lsl #8
  469. cmp r4, lr, lsl #24
  470. bge .rtrloop_outer_exit
  471. add r11, r11, #328*8
  472. b .rtrloop_outer
  473. .rtrloop_outer_exit:
  474. @ terminate cache list
  475. mov r0, #0
  476. str r0, [r6] @ save cache pointer
  477. ldmfd sp!, {r4-r11,lr}
  478. bx lr
  479. .pool
  480. @ void DrawTilesFromCacheF(int *hc, struct PicoEState *est)
  481. .global DrawTilesFromCacheF
  482. DrawTilesFromCacheF:
  483. stmfd sp!, {r4-r10,lr}
  484. mov r9, #0xff000000 @ r9=prevcode=-1
  485. mvn r6, #0 @ r6=prevy=-1
  486. ldr r4, [r1, #OFS_EST_Draw2FB]
  487. ldr r2, [r0], #4 @ read y offset
  488. mov r7, #328
  489. mla r2, r7, r2, r4
  490. sub r12, r2, #(328*8*START_ROW) @ r12=scrpos
  491. ldr r10, [r1, #OFS_EST_PicoMem_vram]
  492. mov r8, r0 @ hc
  493. mov r0, #0xf
  494. @ scratch: r4, r7
  495. @ *hcache++ = code|(dx<<16)|(trow<<27); // cache it
  496. .dtfcf_loop:
  497. ldr r7, [r8], #4 @ read code
  498. movs r1, r7, lsr #16 @ r1=dx;
  499. ldmeqfd sp!, {r4-r10,pc} @ dx is never zero, this must be a terminator, return
  500. @ row changed?
  501. cmp r6, r7, lsr #27
  502. movne r6, r7, lsr #27
  503. movne r4, #328*8
  504. mlane r5, r4, r6, r12 @ r5=pd = scrpos + prevy*328*8
  505. bic r1, r1, #0xf800
  506. add r1, r5, r1 @ r1=pdest (halfwords)
  507. mov r7, r7, lsl #16
  508. mov r7, r7, lsr #16
  509. cmp r7, r9, lsr #8
  510. bne .dtfcf_notsamecode
  511. @ we know stuff about this tile already
  512. tst r9, #1
  513. bne .dtfcf_loop @ empty tile
  514. tst r9, #2
  515. bne .dtfcf_singlecolor @ singlecolor tile
  516. b .dtfcf_samecode
  517. .dtfcf_notsamecode:
  518. and r4, r9, #0x600000
  519. mov r9, r7, lsl #8 @ remember new code
  520. @ update cram val
  521. and r7, r7, #0x6000
  522. mov r3, r7, asr #9 @ r3=pal=((code&0x6000)>>9);
  523. .dtfcf_samecode:
  524. tst r9, #0x100000 @ vflip?
  525. bne .dtfcf_vflip
  526. tst r9, #0x080000 @ hflip?
  527. bne .dtfcf_hflip
  528. @ Tile (r1=pdest, r3=pal, r9=prevcode, r10=Pico.vram) r2,r4,r7: scratch, r0=0xf
  529. Tile 0, 0
  530. b .dtfcf_loop
  531. .dtfcf_hflip:
  532. Tile 1, 0
  533. b .dtfcf_loop
  534. .dtfcf_vflip:
  535. tst r9, #0x080000 @ hflip?
  536. bne .dtfcf_vflip_hflip
  537. Tile 0, 1
  538. b .dtfcf_loop
  539. .dtfcf_vflip_hflip:
  540. Tile 1, 1
  541. b .dtfcf_loop
  542. .dtfcf_singlecolor:
  543. TileSinglecol
  544. b .dtfcf_loop
  545. .pool
  546. @ @@@@@@@@@@@@@@@
  547. @ (tile_start<<16)|row_start
  548. @ void DrawWindowFull(int start, int end, int prio, struct PicoEState *est)
  549. .global DrawWindowFull
  550. DrawWindowFull:
  551. stmfd sp!, {r4-r11,lr}
  552. ldr r11, [r3, #OFS_EST_Pico]
  553. ldrb r12, [r11, #OFS_Pico_video_reg+3] @ pvid->reg[3]
  554. mov r12, r12, lsl #10
  555. ldr r4, [r11, #OFS_Pico_video_reg+12]
  556. mov r5, #1 @ nametab_step
  557. tst r4, #1 @ 40 cell mode?
  558. andne r12, r12, #0xf000 @ 0x3c<<10
  559. andeq r12, r12, #0xf800
  560. movne r5, r5, lsl #7
  561. moveq r5, r5, lsl #6 @ nametab_step
  562. and r4, r0, #0xff
  563. mla r12, r5, r4, r12 @ nametab += nametab_step*start;
  564. ldr r10, [r3, #OFS_EST_PicoMem_vram]
  565. mov r4, r0, lsr #16 @ r4=start_cell_h
  566. add r7, r12, r4, lsl #1
  567. @ fetch the first code now
  568. ldrh r7, [r10, r7]
  569. cmp r2, r7, lsr #15
  570. ldmnefd sp!, {r4-r11,pc} @ hack: simply assume that whole window uses same priority
  571. rsb r8, r4, r1, lsr #16 @ cells (h)
  572. orr r8, r8, r4, lsl #8
  573. mov r4, r1, lsl #24
  574. sub r4, r4, r0, lsl #24
  575. orr r8, r8, r4, lsr #8 @ r8=cells_h|(start_cell_h<<8)|(cells_v<<16)
  576. sub r8, r8, #0x010000 @ adjust for algo
  577. mov r9, #0xff000000 @ r9=prevcode=-1
  578. ldr r11, [r3, #OFS_EST_Draw2FB]
  579. and r4, r0, #0xff
  580. add r11, r11, #328*8
  581. sub r4, r4, #START_ROW
  582. add r11, r11, #8
  583. mov r7, #328*8
  584. mla r11, r7, r4, r11 @ scrpos+=8*328*(start-START_ROW);
  585. mov r0, #0xf
  586. .dwfloop_outer:
  587. and r6, r8, #0xff00 @ r6=tilex
  588. add r1, r11, r6, lsr #5 @ r1=pdest
  589. add r6, r12, r6, lsr #7
  590. add r6, r10, r6 @ r6=Pico.vram+nametab+tilex
  591. orr r8, r8, r8, lsl #24
  592. sub r8, r8, #0x01000000 @ cell loop counter
  593. b .dwfloop_enter
  594. @ r4 & r7 are scratch in this loop
  595. .dwfloop:
  596. add r1, r1, #8
  597. subs r8, r8, #0x01000000
  598. bmi .dwfloop_exit
  599. .dwfloop_enter:
  600. ldrh r7, [r6], #2 @ r7=code
  601. cmp r7, r9, lsr #8
  602. bne .dwf_notsamecode
  603. @ we know stuff about this tile already
  604. tst r9, #1
  605. bne .dwfloop @ empty tile
  606. tst r9, #2
  607. bne .dwf_singlecolor @ singlecolor tile
  608. b .dwf_samecode
  609. .dwf_notsamecode:
  610. and r4, r9, #0x600000
  611. mov r9, r7, lsl #8 @ remember new code
  612. @ update cram val
  613. and r7, r7, #0x6000
  614. mov r3, r7, asr #9 @ r3=pal=((code&0x6000)>>9);
  615. .dwf_samecode:
  616. tst r9, #0x100000 @ vflip?
  617. bne .dwf_vflip
  618. tst r9, #0x080000 @ hflip?
  619. bne .dwf_hflip
  620. @ Tile (r1=pdest, r3=pal, r9=prevcode, r10=PicoMem.vram)
  621. @ r2,r4,r7: scratch, r0=0xf
  622. Tile 0, 0
  623. b .dwfloop
  624. .dwf_hflip:
  625. Tile 1, 0
  626. b .dwfloop
  627. .dwf_vflip:
  628. tst r9, #0x080000 @ hflip?
  629. bne .dwf_vflip_hflip
  630. Tile 0, 1
  631. b .dwfloop
  632. .dwf_vflip_hflip:
  633. Tile 1, 1
  634. b .dwfloop
  635. .dwf_singlecolor:
  636. TileSinglecol 1
  637. b .dwfloop
  638. .dwfloop_exit:
  639. bic r8, r8, #0xff000000 @ fix r8
  640. subs r8, r8, #0x010000
  641. ldmmifd sp!, {r4-r11,pc}
  642. add r11, r11, #328*8
  643. add r12, r12, r5 @ nametab+=nametab_step
  644. b .dwfloop_outer
  645. .pool
  646. @ ---------------- sprites ---------------
  647. .macro SpriteLoop hflip vflip
  648. .if \vflip
  649. mov r1, r5, lsr #24 @ height
  650. mov r0, #328*8
  651. mla r11, r1, r0, r11 @ scrpos+=height*328*8;
  652. add r12, r12, r1, lsl #3 @ sy+=height*8
  653. .endif
  654. mov r0, #0xf
  655. .if \hflip
  656. and r1, r5, #0xff
  657. add r8, r8, r1, lsl #3 @ sx+=width*8
  658. 58:
  659. cmp r8, #336
  660. blt 51f
  661. add r9, r9, r5, lsr #16
  662. sub r5, r5, #1 @ sub width
  663. sub r8, r8, #8
  664. b 58b
  665. .else
  666. cmp r8, #0 @ skip tiles hidden on the left of screen
  667. bgt 51f
  668. 58:
  669. add r9, r9, r5, lsr #16
  670. sub r5, r5, #1
  671. adds r8, r8, #8
  672. ble 58b
  673. b 51f
  674. .endif
  675. 50: @ outer
  676. .if !\hflip
  677. add r8, r8, #8 @ sx+=8
  678. .endif
  679. bic r5, r5, #0xff000000 @ fix height
  680. orr r5, r5, r5, lsl #16
  681. 51: @ outer_enter
  682. sub r5, r5, #1 @ width--
  683. movs r1, r5, lsl #24
  684. ldmmifd sp!, {r4-r11,pc} @ end of tile
  685. .if \hflip
  686. subs r8, r8, #8 @ sx-=8
  687. ldmlefd sp!, {r4-r11,pc} @ tile offscreen
  688. .else
  689. cmp r8, #328
  690. ldmgefd sp!, {r4-r11,pc} @ tile offscreen
  691. .endif
  692. mov r6, r12 @ r6=sy
  693. add r1, r11, r8 @ pdest=scrpos+sx
  694. b 53f
  695. 52: @ inner
  696. add r9, r9, #1<<8 @ tile++
  697. .if !\vflip
  698. add r6, r6, #8 @ sy+=8
  699. add r1, r1, #328*8
  700. .endif
  701. 53: @ inner_enter
  702. @ end of sprite?
  703. subs r5, r5, #0x01000000
  704. bmi 50b @ ->outer
  705. .if \vflip
  706. sub r6, r6, #8 @ sy-=8
  707. sub r1, r1, #328*8
  708. .endif
  709. @ offscreen?
  710. cmp r6, #(START_ROW*8)
  711. ble 52b
  712. cmp r6, #(END_ROW*8+8)
  713. bge 52b
  714. @ Tile (r1=pdest, r3=pal, r9=prevcode, r10=PicoMem.vram)
  715. @ r2,r4,r7: scratch, r0=0xf
  716. Tile \hflip, \vflip
  717. b 52b
  718. .endm
  719. @ void DrawSpriteFull(unsigned int *sprite, struct PicoEState *est)
  720. .global DrawSpriteFull
  721. DrawSpriteFull:
  722. stmfd sp!, {r4-r11,lr}
  723. ldr r3, [r0] @ sprite[0]
  724. mov r5, r3, lsl #4
  725. mov r6, r5, lsr #30
  726. add r6, r6, #1 @ r6=width
  727. mov r5, r5, lsl #2
  728. mov r5, r5, lsr #30
  729. add r5, r5, #1 @ r5=height
  730. mov r12, r3, lsl #23
  731. mov r12, r12, lsr #23
  732. ldr lr, [r0, #4] @ lr=code
  733. sub r12, r12, #0x78 @ r12=sy
  734. mov r8, lr, lsl #7
  735. mov r8, r8, lsr #23
  736. sub r8, r8, #0x78 @ r8=sx
  737. mov r9, lr, lsl #21
  738. mov r9, r9, lsr #13 @ r9=tile<<8
  739. and r3, lr, #0x6000
  740. mov r3, r3, lsr #9 @ r3=pal=((code>>9)&0x30);
  741. ldr r11, [r1, #OFS_EST_Draw2FB]
  742. ldr r10, [r1, #OFS_EST_PicoMem_vram]
  743. sub r1, r12, #(START_ROW*8)
  744. mov r0, #328
  745. mla r11, r1, r0, r11 @ scrpos+=(sy-START_ROW*8)*328;
  746. orr r5, r5, r5, lsl #16 @
  747. orr r5, r6, r5, lsl #8 @ r5=width|(height<<8)|(height<<24)
  748. tst lr, #0x1000 @ vflip?
  749. bne .dsf_vflip
  750. tst lr, #0x0800 @ hflip?
  751. bne .dsf_hflip
  752. SpriteLoop 0, 0
  753. .dsf_hflip:
  754. SpriteLoop 1, 0
  755. .dsf_vflip:
  756. tst lr, #0x0800 @ hflip?
  757. bne .dsf_vflip_hflip
  758. SpriteLoop 0, 1
  759. .dsf_vflip_hflip:
  760. SpriteLoop 1, 1
  761. .pool
  762. @ vim:filetype=armasm