draw2_arm.S 25 KB

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