surf8.s 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784
  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. //
  16. // surf8.s
  17. // x86 assembly-language 8 bpp surface block drawing code.
  18. //
  19. #include "asm_i386.h"
  20. #include "quakeasm.h"
  21. #include "asm_draw.h"
  22. #if id386
  23. .data
  24. sb_v: .long 0
  25. .text
  26. .align 4
  27. .globl C(R_Surf8Start)
  28. C(R_Surf8Start):
  29. //----------------------------------------------------------------------
  30. // Surface block drawer for mip level 0
  31. //----------------------------------------------------------------------
  32. .align 4
  33. .globl C(R_DrawSurfaceBlock8_mip0)
  34. C(R_DrawSurfaceBlock8_mip0):
  35. pushl %ebp // preserve caller's stack frame
  36. pushl %edi
  37. pushl %esi // preserve register variables
  38. pushl %ebx
  39. // for (v=0 ; v<numvblocks ; v++)
  40. // {
  41. movl C(r_lightptr),%ebx
  42. movl C(r_numvblocks),%eax
  43. movl %eax,sb_v
  44. movl C(prowdestbase),%edi
  45. movl C(pbasesource),%esi
  46. Lv_loop_mip0:
  47. // lightleft = lightptr[0];
  48. // lightright = lightptr[1];
  49. // lightdelta = (lightleft - lightright) & 0xFFFFF;
  50. movl (%ebx),%eax // lightleft
  51. movl 4(%ebx),%edx // lightright
  52. movl %eax,%ebp
  53. movl C(r_lightwidth),%ecx
  54. movl %edx,C(lightright)
  55. subl %edx,%ebp
  56. andl $0xFFFFF,%ebp
  57. leal (%ebx,%ecx,4),%ebx
  58. // lightptr += lightwidth;
  59. movl %ebx,C(r_lightptr)
  60. // lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
  61. // lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
  62. // lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
  63. // 0xF0000000;
  64. movl 4(%ebx),%ecx // lightptr[1]
  65. movl (%ebx),%ebx // lightptr[0]
  66. subl %eax,%ebx
  67. subl %edx,%ecx
  68. sarl $4,%ecx
  69. orl $0xF0000000,%ebp
  70. sarl $4,%ebx
  71. movl %ecx,C(lightrightstep)
  72. subl %ecx,%ebx
  73. andl $0xFFFFF,%ebx
  74. orl $0xF0000000,%ebx
  75. subl %ecx,%ecx // high word must be 0 in loop for addressing
  76. movl %ebx,C(lightdeltastep)
  77. subl %ebx,%ebx // high word must be 0 in loop for addressing
  78. Lblockloop8_mip0:
  79. movl %ebp,C(lightdelta)
  80. movb 14(%esi),%cl
  81. sarl $4,%ebp
  82. movb %dh,%bh
  83. movb 15(%esi),%bl
  84. addl %ebp,%edx
  85. movb %dh,%ch
  86. addl %ebp,%edx
  87. movb 0x12345678(%ebx),%ah
  88. LBPatch0:
  89. movb 13(%esi),%bl
  90. movb 0x12345678(%ecx),%al
  91. LBPatch1:
  92. movb 12(%esi),%cl
  93. movb %dh,%bh
  94. addl %ebp,%edx
  95. rorl $16,%eax
  96. movb %dh,%ch
  97. addl %ebp,%edx
  98. movb 0x12345678(%ebx),%ah
  99. LBPatch2:
  100. movb 11(%esi),%bl
  101. movb 0x12345678(%ecx),%al
  102. LBPatch3:
  103. movb 10(%esi),%cl
  104. movl %eax,12(%edi)
  105. movb %dh,%bh
  106. addl %ebp,%edx
  107. movb %dh,%ch
  108. addl %ebp,%edx
  109. movb 0x12345678(%ebx),%ah
  110. LBPatch4:
  111. movb 9(%esi),%bl
  112. movb 0x12345678(%ecx),%al
  113. LBPatch5:
  114. movb 8(%esi),%cl
  115. movb %dh,%bh
  116. addl %ebp,%edx
  117. rorl $16,%eax
  118. movb %dh,%ch
  119. addl %ebp,%edx
  120. movb 0x12345678(%ebx),%ah
  121. LBPatch6:
  122. movb 7(%esi),%bl
  123. movb 0x12345678(%ecx),%al
  124. LBPatch7:
  125. movb 6(%esi),%cl
  126. movl %eax,8(%edi)
  127. movb %dh,%bh
  128. addl %ebp,%edx
  129. movb %dh,%ch
  130. addl %ebp,%edx
  131. movb 0x12345678(%ebx),%ah
  132. LBPatch8:
  133. movb 5(%esi),%bl
  134. movb 0x12345678(%ecx),%al
  135. LBPatch9:
  136. movb 4(%esi),%cl
  137. movb %dh,%bh
  138. addl %ebp,%edx
  139. rorl $16,%eax
  140. movb %dh,%ch
  141. addl %ebp,%edx
  142. movb 0x12345678(%ebx),%ah
  143. LBPatch10:
  144. movb 3(%esi),%bl
  145. movb 0x12345678(%ecx),%al
  146. LBPatch11:
  147. movb 2(%esi),%cl
  148. movl %eax,4(%edi)
  149. movb %dh,%bh
  150. addl %ebp,%edx
  151. movb %dh,%ch
  152. addl %ebp,%edx
  153. movb 0x12345678(%ebx),%ah
  154. LBPatch12:
  155. movb 1(%esi),%bl
  156. movb 0x12345678(%ecx),%al
  157. LBPatch13:
  158. movb (%esi),%cl
  159. movb %dh,%bh
  160. addl %ebp,%edx
  161. rorl $16,%eax
  162. movb %dh,%ch
  163. movb 0x12345678(%ebx),%ah
  164. LBPatch14:
  165. movl C(lightright),%edx
  166. movb 0x12345678(%ecx),%al
  167. LBPatch15:
  168. movl C(lightdelta),%ebp
  169. movl %eax,(%edi)
  170. addl C(sourcetstep),%esi
  171. addl C(surfrowbytes),%edi
  172. addl C(lightrightstep),%edx
  173. addl C(lightdeltastep),%ebp
  174. movl %edx,C(lightright)
  175. jc Lblockloop8_mip0
  176. // if (pbasesource >= r_sourcemax)
  177. // pbasesource -= stepback;
  178. cmpl C(r_sourcemax),%esi
  179. jb LSkip_mip0
  180. subl C(r_stepback),%esi
  181. LSkip_mip0:
  182. movl C(r_lightptr),%ebx
  183. decl sb_v
  184. jnz Lv_loop_mip0
  185. popl %ebx // restore register variables
  186. popl %esi
  187. popl %edi
  188. popl %ebp // restore the caller's stack frame
  189. ret
  190. //----------------------------------------------------------------------
  191. // Surface block drawer for mip level 1
  192. //----------------------------------------------------------------------
  193. .align 4
  194. .globl C(R_DrawSurfaceBlock8_mip1)
  195. C(R_DrawSurfaceBlock8_mip1):
  196. pushl %ebp // preserve caller's stack frame
  197. pushl %edi
  198. pushl %esi // preserve register variables
  199. pushl %ebx
  200. // for (v=0 ; v<numvblocks ; v++)
  201. // {
  202. movl C(r_lightptr),%ebx
  203. movl C(r_numvblocks),%eax
  204. movl %eax,sb_v
  205. movl C(prowdestbase),%edi
  206. movl C(pbasesource),%esi
  207. Lv_loop_mip1:
  208. // lightleft = lightptr[0];
  209. // lightright = lightptr[1];
  210. // lightdelta = (lightleft - lightright) & 0xFFFFF;
  211. movl (%ebx),%eax // lightleft
  212. movl 4(%ebx),%edx // lightright
  213. movl %eax,%ebp
  214. movl C(r_lightwidth),%ecx
  215. movl %edx,C(lightright)
  216. subl %edx,%ebp
  217. andl $0xFFFFF,%ebp
  218. leal (%ebx,%ecx,4),%ebx
  219. // lightptr += lightwidth;
  220. movl %ebx,C(r_lightptr)
  221. // lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
  222. // lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
  223. // lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
  224. // 0xF0000000;
  225. movl 4(%ebx),%ecx // lightptr[1]
  226. movl (%ebx),%ebx // lightptr[0]
  227. subl %eax,%ebx
  228. subl %edx,%ecx
  229. sarl $3,%ecx
  230. orl $0x70000000,%ebp
  231. sarl $3,%ebx
  232. movl %ecx,C(lightrightstep)
  233. subl %ecx,%ebx
  234. andl $0xFFFFF,%ebx
  235. orl $0xF0000000,%ebx
  236. subl %ecx,%ecx // high word must be 0 in loop for addressing
  237. movl %ebx,C(lightdeltastep)
  238. subl %ebx,%ebx // high word must be 0 in loop for addressing
  239. Lblockloop8_mip1:
  240. movl %ebp,C(lightdelta)
  241. movb 6(%esi),%cl
  242. sarl $3,%ebp
  243. movb %dh,%bh
  244. movb 7(%esi),%bl
  245. addl %ebp,%edx
  246. movb %dh,%ch
  247. addl %ebp,%edx
  248. movb 0x12345678(%ebx),%ah
  249. LBPatch22:
  250. movb 5(%esi),%bl
  251. movb 0x12345678(%ecx),%al
  252. LBPatch23:
  253. movb 4(%esi),%cl
  254. movb %dh,%bh
  255. addl %ebp,%edx
  256. rorl $16,%eax
  257. movb %dh,%ch
  258. addl %ebp,%edx
  259. movb 0x12345678(%ebx),%ah
  260. LBPatch24:
  261. movb 3(%esi),%bl
  262. movb 0x12345678(%ecx),%al
  263. LBPatch25:
  264. movb 2(%esi),%cl
  265. movl %eax,4(%edi)
  266. movb %dh,%bh
  267. addl %ebp,%edx
  268. movb %dh,%ch
  269. addl %ebp,%edx
  270. movb 0x12345678(%ebx),%ah
  271. LBPatch26:
  272. movb 1(%esi),%bl
  273. movb 0x12345678(%ecx),%al
  274. LBPatch27:
  275. movb (%esi),%cl
  276. movb %dh,%bh
  277. addl %ebp,%edx
  278. rorl $16,%eax
  279. movb %dh,%ch
  280. movb 0x12345678(%ebx),%ah
  281. LBPatch28:
  282. movl C(lightright),%edx
  283. movb 0x12345678(%ecx),%al
  284. LBPatch29:
  285. movl C(lightdelta),%ebp
  286. movl %eax,(%edi)
  287. movl C(sourcetstep),%eax
  288. addl %eax,%esi
  289. movl C(surfrowbytes),%eax
  290. addl %eax,%edi
  291. movl C(lightrightstep),%eax
  292. addl %eax,%edx
  293. movl C(lightdeltastep),%eax
  294. addl %eax,%ebp
  295. movl %edx,C(lightright)
  296. jc Lblockloop8_mip1
  297. // if (pbasesource >= r_sourcemax)
  298. // pbasesource -= stepback;
  299. cmpl C(r_sourcemax),%esi
  300. jb LSkip_mip1
  301. subl C(r_stepback),%esi
  302. LSkip_mip1:
  303. movl C(r_lightptr),%ebx
  304. decl sb_v
  305. jnz Lv_loop_mip1
  306. popl %ebx // restore register variables
  307. popl %esi
  308. popl %edi
  309. popl %ebp // restore the caller's stack frame
  310. ret
  311. //----------------------------------------------------------------------
  312. // Surface block drawer for mip level 2
  313. //----------------------------------------------------------------------
  314. .align 4
  315. .globl C(R_DrawSurfaceBlock8_mip2)
  316. C(R_DrawSurfaceBlock8_mip2):
  317. pushl %ebp // preserve caller's stack frame
  318. pushl %edi
  319. pushl %esi // preserve register variables
  320. pushl %ebx
  321. // for (v=0 ; v<numvblocks ; v++)
  322. // {
  323. movl C(r_lightptr),%ebx
  324. movl C(r_numvblocks),%eax
  325. movl %eax,sb_v
  326. movl C(prowdestbase),%edi
  327. movl C(pbasesource),%esi
  328. Lv_loop_mip2:
  329. // lightleft = lightptr[0];
  330. // lightright = lightptr[1];
  331. // lightdelta = (lightleft - lightright) & 0xFFFFF;
  332. movl (%ebx),%eax // lightleft
  333. movl 4(%ebx),%edx // lightright
  334. movl %eax,%ebp
  335. movl C(r_lightwidth),%ecx
  336. movl %edx,C(lightright)
  337. subl %edx,%ebp
  338. andl $0xFFFFF,%ebp
  339. leal (%ebx,%ecx,4),%ebx
  340. // lightptr += lightwidth;
  341. movl %ebx,C(r_lightptr)
  342. // lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
  343. // lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
  344. // lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
  345. // 0xF0000000;
  346. movl 4(%ebx),%ecx // lightptr[1]
  347. movl (%ebx),%ebx // lightptr[0]
  348. subl %eax,%ebx
  349. subl %edx,%ecx
  350. sarl $2,%ecx
  351. orl $0x30000000,%ebp
  352. sarl $2,%ebx
  353. movl %ecx,C(lightrightstep)
  354. subl %ecx,%ebx
  355. andl $0xFFFFF,%ebx
  356. orl $0xF0000000,%ebx
  357. subl %ecx,%ecx // high word must be 0 in loop for addressing
  358. movl %ebx,C(lightdeltastep)
  359. subl %ebx,%ebx // high word must be 0 in loop for addressing
  360. Lblockloop8_mip2:
  361. movl %ebp,C(lightdelta)
  362. movb 2(%esi),%cl
  363. sarl $2,%ebp
  364. movb %dh,%bh
  365. movb 3(%esi),%bl
  366. addl %ebp,%edx
  367. movb %dh,%ch
  368. addl %ebp,%edx
  369. movb 0x12345678(%ebx),%ah
  370. LBPatch18:
  371. movb 1(%esi),%bl
  372. movb 0x12345678(%ecx),%al
  373. LBPatch19:
  374. movb (%esi),%cl
  375. movb %dh,%bh
  376. addl %ebp,%edx
  377. rorl $16,%eax
  378. movb %dh,%ch
  379. movb 0x12345678(%ebx),%ah
  380. LBPatch20:
  381. movl C(lightright),%edx
  382. movb 0x12345678(%ecx),%al
  383. LBPatch21:
  384. movl C(lightdelta),%ebp
  385. movl %eax,(%edi)
  386. movl C(sourcetstep),%eax
  387. addl %eax,%esi
  388. movl C(surfrowbytes),%eax
  389. addl %eax,%edi
  390. movl C(lightrightstep),%eax
  391. addl %eax,%edx
  392. movl C(lightdeltastep),%eax
  393. addl %eax,%ebp
  394. movl %edx,C(lightright)
  395. jc Lblockloop8_mip2
  396. // if (pbasesource >= r_sourcemax)
  397. // pbasesource -= stepback;
  398. cmpl C(r_sourcemax),%esi
  399. jb LSkip_mip2
  400. subl C(r_stepback),%esi
  401. LSkip_mip2:
  402. movl C(r_lightptr),%ebx
  403. decl sb_v
  404. jnz Lv_loop_mip2
  405. popl %ebx // restore register variables
  406. popl %esi
  407. popl %edi
  408. popl %ebp // restore the caller's stack frame
  409. ret
  410. //----------------------------------------------------------------------
  411. // Surface block drawer for mip level 3
  412. //----------------------------------------------------------------------
  413. .align 4
  414. .globl C(R_DrawSurfaceBlock8_mip3)
  415. C(R_DrawSurfaceBlock8_mip3):
  416. pushl %ebp // preserve caller's stack frame
  417. pushl %edi
  418. pushl %esi // preserve register variables
  419. pushl %ebx
  420. // for (v=0 ; v<numvblocks ; v++)
  421. // {
  422. movl C(r_lightptr),%ebx
  423. movl C(r_numvblocks),%eax
  424. movl %eax,sb_v
  425. movl C(prowdestbase),%edi
  426. movl C(pbasesource),%esi
  427. Lv_loop_mip3:
  428. // lightleft = lightptr[0];
  429. // lightright = lightptr[1];
  430. // lightdelta = (lightleft - lightright) & 0xFFFFF;
  431. movl (%ebx),%eax // lightleft
  432. movl 4(%ebx),%edx // lightright
  433. movl %eax,%ebp
  434. movl C(r_lightwidth),%ecx
  435. movl %edx,C(lightright)
  436. subl %edx,%ebp
  437. andl $0xFFFFF,%ebp
  438. leal (%ebx,%ecx,4),%ebx
  439. movl %ebp,C(lightdelta)
  440. // lightptr += lightwidth;
  441. movl %ebx,C(r_lightptr)
  442. // lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
  443. // lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
  444. // lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
  445. // 0xF0000000;
  446. movl 4(%ebx),%ecx // lightptr[1]
  447. movl (%ebx),%ebx // lightptr[0]
  448. subl %eax,%ebx
  449. subl %edx,%ecx
  450. sarl $1,%ecx
  451. sarl $1,%ebx
  452. movl %ecx,C(lightrightstep)
  453. subl %ecx,%ebx
  454. andl $0xFFFFF,%ebx
  455. sarl $1,%ebp
  456. orl $0xF0000000,%ebx
  457. movl %ebx,C(lightdeltastep)
  458. subl %ebx,%ebx // high word must be 0 in loop for addressing
  459. movb 1(%esi),%bl
  460. subl %ecx,%ecx // high word must be 0 in loop for addressing
  461. movb %dh,%bh
  462. movb (%esi),%cl
  463. addl %ebp,%edx
  464. movb %dh,%ch
  465. movb 0x12345678(%ebx),%al
  466. LBPatch16:
  467. movl C(lightright),%edx
  468. movb %al,1(%edi)
  469. movb 0x12345678(%ecx),%al
  470. LBPatch17:
  471. movb %al,(%edi)
  472. movl C(sourcetstep),%eax
  473. addl %eax,%esi
  474. movl C(surfrowbytes),%eax
  475. addl %eax,%edi
  476. movl C(lightdeltastep),%eax
  477. movl C(lightdelta),%ebp
  478. movb (%esi),%cl
  479. addl %eax,%ebp
  480. movl C(lightrightstep),%eax
  481. sarl $1,%ebp
  482. addl %eax,%edx
  483. movb %dh,%bh
  484. movb 1(%esi),%bl
  485. addl %ebp,%edx
  486. movb %dh,%ch
  487. movb 0x12345678(%ebx),%al
  488. LBPatch30:
  489. movl C(sourcetstep),%edx
  490. movb %al,1(%edi)
  491. movb 0x12345678(%ecx),%al
  492. LBPatch31:
  493. movb %al,(%edi)
  494. movl C(surfrowbytes),%ebp
  495. addl %edx,%esi
  496. addl %ebp,%edi
  497. // if (pbasesource >= r_sourcemax)
  498. // pbasesource -= stepback;
  499. cmpl C(r_sourcemax),%esi
  500. jb LSkip_mip3
  501. subl C(r_stepback),%esi
  502. LSkip_mip3:
  503. movl C(r_lightptr),%ebx
  504. decl sb_v
  505. jnz Lv_loop_mip3
  506. popl %ebx // restore register variables
  507. popl %esi
  508. popl %edi
  509. popl %ebp // restore the caller's stack frame
  510. ret
  511. .globl C(R_Surf8End)
  512. C(R_Surf8End):
  513. //----------------------------------------------------------------------
  514. // Code patching routines
  515. //----------------------------------------------------------------------
  516. .data
  517. .align 4
  518. LPatchTable8:
  519. .long LBPatch0-4
  520. .long LBPatch1-4
  521. .long LBPatch2-4
  522. .long LBPatch3-4
  523. .long LBPatch4-4
  524. .long LBPatch5-4
  525. .long LBPatch6-4
  526. .long LBPatch7-4
  527. .long LBPatch8-4
  528. .long LBPatch9-4
  529. .long LBPatch10-4
  530. .long LBPatch11-4
  531. .long LBPatch12-4
  532. .long LBPatch13-4
  533. .long LBPatch14-4
  534. .long LBPatch15-4
  535. .long LBPatch16-4
  536. .long LBPatch17-4
  537. .long LBPatch18-4
  538. .long LBPatch19-4
  539. .long LBPatch20-4
  540. .long LBPatch21-4
  541. .long LBPatch22-4
  542. .long LBPatch23-4
  543. .long LBPatch24-4
  544. .long LBPatch25-4
  545. .long LBPatch26-4
  546. .long LBPatch27-4
  547. .long LBPatch28-4
  548. .long LBPatch29-4
  549. .long LBPatch30-4
  550. .long LBPatch31-4
  551. .text
  552. .align 4
  553. .globl C(R_Surf8Patch)
  554. C(R_Surf8Patch):
  555. pushl %ebx
  556. movl C(colormap),%eax
  557. movl $LPatchTable8,%ebx
  558. movl $32,%ecx
  559. LPatchLoop8:
  560. movl (%ebx),%edx
  561. addl $4,%ebx
  562. movl %eax,(%edx)
  563. decl %ecx
  564. jnz LPatchLoop8
  565. popl %ebx
  566. ret
  567. #endif // id386