draw2_arm.s 24 KB

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