1 /* 2 Copyright (C) 1996-1997 Id Software, Inc. 3 4 This program is free software; you can redistribute it and/or 5 modify it under the terms of the GNU General Public License 6 as published by the Free Software Foundation; either version 2 7 of the License, or (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 13 See the GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 19 */ 20 // 21 // surf8.s 22 // x86 assembly-language 8 bpp surface block drawing code. 23 // 24 25 #include "asm_i386.h" 26 #include "quakeasm.h" 27 #include "asm_draw.h" 28 29 #if id386 30 31 .data 32 33 sb_v: .long 0 34 35 .text 36 37 .align 4 38 .globl C(R_Surf8Start) 39 C(R_Surf8Start): 40 41 //---------------------------------------------------------------------- 42 // Surface block drawer for mip level 0 43 //---------------------------------------------------------------------- 44 45 .align 4 46 .globl C(R_DrawSurfaceBlock8_mip0) 47 C(R_DrawSurfaceBlock8_mip0): 48 pushl %ebp // preserve caller's stack frame 49 pushl %edi 50 pushl %esi // preserve register variables 51 pushl %ebx 52 53 // for (v=0 ; v<numvblocks ; v++) 54 // { 55 movl C(r_lightptr),%ebx 56 movl C(r_numvblocks),%eax 57 58 movl %eax,sb_v 59 movl C(prowdestbase),%edi 60 61 movl C(pbasesource),%esi 62 63 Lv_loop_mip0: 64 65 // lightleft = lightptr[0]; 66 // lightright = lightptr[1]; 67 // lightdelta = (lightleft - lightright) & 0xFFFFF; 68 movl (%ebx),%eax // lightleft 69 movl 4(%ebx),%edx // lightright 70 71 movl %eax,%ebp 72 movl C(r_lightwidth),%ecx 73 74 movl %edx,C(lightright) 75 subl %edx,%ebp 76 77 andl $0xFFFFF,%ebp 78 leal (%ebx,%ecx,4),%ebx 79 80 // lightptr += lightwidth; 81 movl %ebx,C(r_lightptr) 82 83 // lightleftstep = (lightptr[0] - lightleft) >> blockdivshift; 84 // lightrightstep = (lightptr[1] - lightright) >> blockdivshift; 85 // lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) | 86 // 0xF0000000; 87 movl 4(%ebx),%ecx // lightptr[1] 88 movl (%ebx),%ebx // lightptr[0] 89 90 subl %eax,%ebx 91 subl %edx,%ecx 92 93 sarl $4,%ecx 94 orl $0xF0000000,%ebp 95 96 sarl $4,%ebx 97 movl %ecx,C(lightrightstep) 98 99 subl %ecx,%ebx 100 andl $0xFFFFF,%ebx 101 102 orl $0xF0000000,%ebx 103 subl %ecx,%ecx // high word must be 0 in loop for addressing 104 105 movl %ebx,C(lightdeltastep) 106 subl %ebx,%ebx // high word must be 0 in loop for addressing 107 108 Lblockloop8_mip0: 109 movl %ebp,C(lightdelta) 110 movb 14(%esi),%cl 111 112 sarl $4,%ebp 113 movb %dh,%bh 114 115 movb 15(%esi),%bl 116 addl %ebp,%edx 117 118 movb %dh,%ch 119 addl %ebp,%edx 120 121 movb 0x12345678(%ebx),%ah 122 LBPatch0: 123 movb 13(%esi),%bl 124 125 movb 0x12345678(%ecx),%al 126 LBPatch1: 127 movb 12(%esi),%cl 128 129 movb %dh,%bh 130 addl %ebp,%edx 131 132 rorl $16,%eax 133 movb %dh,%ch 134 135 addl %ebp,%edx 136 movb 0x12345678(%ebx),%ah 137 LBPatch2: 138 139 movb 11(%esi),%bl 140 movb 0x12345678(%ecx),%al 141 LBPatch3: 142 143 movb 10(%esi),%cl 144 movl %eax,12(%edi) 145 146 movb %dh,%bh 147 addl %ebp,%edx 148 149 movb %dh,%ch 150 addl %ebp,%edx 151 152 movb 0x12345678(%ebx),%ah 153 LBPatch4: 154 movb 9(%esi),%bl 155 156 movb 0x12345678(%ecx),%al 157 LBPatch5: 158 movb 8(%esi),%cl 159 160 movb %dh,%bh 161 addl %ebp,%edx 162 163 rorl $16,%eax 164 movb %dh,%ch 165 166 addl %ebp,%edx 167 movb 0x12345678(%ebx),%ah 168 LBPatch6: 169 170 movb 7(%esi),%bl 171 movb 0x12345678(%ecx),%al 172 LBPatch7: 173 174 movb 6(%esi),%cl 175 movl %eax,8(%edi) 176 177 movb %dh,%bh 178 addl %ebp,%edx 179 180 movb %dh,%ch 181 addl %ebp,%edx 182 183 movb 0x12345678(%ebx),%ah 184 LBPatch8: 185 movb 5(%esi),%bl 186 187 movb 0x12345678(%ecx),%al 188 LBPatch9: 189 movb 4(%esi),%cl 190 191 movb %dh,%bh 192 addl %ebp,%edx 193 194 rorl $16,%eax 195 movb %dh,%ch 196 197 addl %ebp,%edx 198 movb 0x12345678(%ebx),%ah 199 LBPatch10: 200 201 movb 3(%esi),%bl 202 movb 0x12345678(%ecx),%al 203 LBPatch11: 204 205 movb 2(%esi),%cl 206 movl %eax,4(%edi) 207 208 movb %dh,%bh 209 addl %ebp,%edx 210 211 movb %dh,%ch 212 addl %ebp,%edx 213 214 movb 0x12345678(%ebx),%ah 215 LBPatch12: 216 movb 1(%esi),%bl 217 218 movb 0x12345678(%ecx),%al 219 LBPatch13: 220 movb (%esi),%cl 221 222 movb %dh,%bh 223 addl %ebp,%edx 224 225 rorl $16,%eax 226 movb %dh,%ch 227 228 movb 0x12345678(%ebx),%ah 229 LBPatch14: 230 movl C(lightright),%edx 231 232 movb 0x12345678(%ecx),%al 233 LBPatch15: 234 movl C(lightdelta),%ebp 235 236 movl %eax,(%edi) 237 238 addl C(sourcetstep),%esi 239 addl C(surfrowbytes),%edi 240 241 addl C(lightrightstep),%edx 242 addl C(lightdeltastep),%ebp 243 244 movl %edx,C(lightright) 245 jc Lblockloop8_mip0 246 247 // if (pbasesource >= r_sourcemax) 248 // pbasesource -= stepback; 249 250 cmpl C(r_sourcemax),%esi 251 jb LSkip_mip0 252 subl C(r_stepback),%esi 253 LSkip_mip0: 254 255 movl C(r_lightptr),%ebx 256 decl sb_v 257 258 jnz Lv_loop_mip0 259 260 popl %ebx // restore register variables 261 popl %esi 262 popl %edi 263 popl %ebp // restore the caller's stack frame 264 ret 265 266 267 //---------------------------------------------------------------------- 268 // Surface block drawer for mip level 1 269 //---------------------------------------------------------------------- 270 271 .align 4 272 .globl C(R_DrawSurfaceBlock8_mip1) 273 C(R_DrawSurfaceBlock8_mip1): 274 pushl %ebp // preserve caller's stack frame 275 pushl %edi 276 pushl %esi // preserve register variables 277 pushl %ebx 278 279 // for (v=0 ; v<numvblocks ; v++) 280 // { 281 movl C(r_lightptr),%ebx 282 movl C(r_numvblocks),%eax 283 284 movl %eax,sb_v 285 movl C(prowdestbase),%edi 286 287 movl C(pbasesource),%esi 288 289 Lv_loop_mip1: 290 291 // lightleft = lightptr[0]; 292 // lightright = lightptr[1]; 293 // lightdelta = (lightleft - lightright) & 0xFFFFF; 294 movl (%ebx),%eax // lightleft 295 movl 4(%ebx),%edx // lightright 296 297 movl %eax,%ebp 298 movl C(r_lightwidth),%ecx 299 300 movl %edx,C(lightright) 301 subl %edx,%ebp 302 303 andl $0xFFFFF,%ebp 304 leal (%ebx,%ecx,4),%ebx 305 306 // lightptr += lightwidth; 307 movl %ebx,C(r_lightptr) 308 309 // lightleftstep = (lightptr[0] - lightleft) >> blockdivshift; 310 // lightrightstep = (lightptr[1] - lightright) >> blockdivshift; 311 // lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) | 312 // 0xF0000000; 313 movl 4(%ebx),%ecx // lightptr[1] 314 movl (%ebx),%ebx // lightptr[0] 315 316 subl %eax,%ebx 317 subl %edx,%ecx 318 319 sarl $3,%ecx 320 orl $0x70000000,%ebp 321 322 sarl $3,%ebx 323 movl %ecx,C(lightrightstep) 324 325 subl %ecx,%ebx 326 andl $0xFFFFF,%ebx 327 328 orl $0xF0000000,%ebx 329 subl %ecx,%ecx // high word must be 0 in loop for addressing 330 331 movl %ebx,C(lightdeltastep) 332 subl %ebx,%ebx // high word must be 0 in loop for addressing 333 334 Lblockloop8_mip1: 335 movl %ebp,C(lightdelta) 336 movb 6(%esi),%cl 337 338 sarl $3,%ebp 339 movb %dh,%bh 340 341 movb 7(%esi),%bl 342 addl %ebp,%edx 343 344 movb %dh,%ch 345 addl %ebp,%edx 346 347 movb 0x12345678(%ebx),%ah 348 LBPatch22: 349 movb 5(%esi),%bl 350 351 movb 0x12345678(%ecx),%al 352 LBPatch23: 353 movb 4(%esi),%cl 354 355 movb %dh,%bh 356 addl %ebp,%edx 357 358 rorl $16,%eax 359 movb %dh,%ch 360 361 addl %ebp,%edx 362 movb 0x12345678(%ebx),%ah 363 LBPatch24: 364 365 movb 3(%esi),%bl 366 movb 0x12345678(%ecx),%al 367 LBPatch25: 368 369 movb 2(%esi),%cl 370 movl %eax,4(%edi) 371 372 movb %dh,%bh 373 addl %ebp,%edx 374 375 movb %dh,%ch 376 addl %ebp,%edx 377 378 movb 0x12345678(%ebx),%ah 379 LBPatch26: 380 movb 1(%esi),%bl 381 382 movb 0x12345678(%ecx),%al 383 LBPatch27: 384 movb (%esi),%cl 385 386 movb %dh,%bh 387 addl %ebp,%edx 388 389 rorl $16,%eax 390 movb %dh,%ch 391 392 movb 0x12345678(%ebx),%ah 393 LBPatch28: 394 movl C(lightright),%edx 395 396 movb 0x12345678(%ecx),%al 397 LBPatch29: 398 movl C(lightdelta),%ebp 399 400 movl %eax,(%edi) 401 movl C(sourcetstep),%eax 402 403 addl %eax,%esi 404 movl C(surfrowbytes),%eax 405 406 addl %eax,%edi 407 movl C(lightrightstep),%eax 408 409 addl %eax,%edx 410 movl C(lightdeltastep),%eax 411 412 addl %eax,%ebp 413 movl %edx,C(lightright) 414 415 jc Lblockloop8_mip1 416 417 // if (pbasesource >= r_sourcemax) 418 // pbasesource -= stepback; 419 420 cmpl C(r_sourcemax),%esi 421 jb LSkip_mip1 422 subl C(r_stepback),%esi 423 LSkip_mip1: 424 425 movl C(r_lightptr),%ebx 426 decl sb_v 427 428 jnz Lv_loop_mip1 429 430 popl %ebx // restore register variables 431 popl %esi 432 popl %edi 433 popl %ebp // restore the caller's stack frame 434 ret 435 436 437 //---------------------------------------------------------------------- 438 // Surface block drawer for mip level 2 439 //---------------------------------------------------------------------- 440 441 .align 4 442 .globl C(R_DrawSurfaceBlock8_mip2) 443 C(R_DrawSurfaceBlock8_mip2): 444 pushl %ebp // preserve caller's stack frame 445 pushl %edi 446 pushl %esi // preserve register variables 447 pushl %ebx 448 449 // for (v=0 ; v<numvblocks ; v++) 450 // { 451 movl C(r_lightptr),%ebx 452 movl C(r_numvblocks),%eax 453 454 movl %eax,sb_v 455 movl C(prowdestbase),%edi 456 457 movl C(pbasesource),%esi 458 459 Lv_loop_mip2: 460 461 // lightleft = lightptr[0]; 462 // lightright = lightptr[1]; 463 // lightdelta = (lightleft - lightright) & 0xFFFFF; 464 movl (%ebx),%eax // lightleft 465 movl 4(%ebx),%edx // lightright 466 467 movl %eax,%ebp 468 movl C(r_lightwidth),%ecx 469 470 movl %edx,C(lightright) 471 subl %edx,%ebp 472 473 andl $0xFFFFF,%ebp 474 leal (%ebx,%ecx,4),%ebx 475 476 // lightptr += lightwidth; 477 movl %ebx,C(r_lightptr) 478 479 // lightleftstep = (lightptr[0] - lightleft) >> blockdivshift; 480 // lightrightstep = (lightptr[1] - lightright) >> blockdivshift; 481 // lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) | 482 // 0xF0000000; 483 movl 4(%ebx),%ecx // lightptr[1] 484 movl (%ebx),%ebx // lightptr[0] 485 486 subl %eax,%ebx 487 subl %edx,%ecx 488 489 sarl $2,%ecx 490 orl $0x30000000,%ebp 491 492 sarl $2,%ebx 493 movl %ecx,C(lightrightstep) 494 495 subl %ecx,%ebx 496 497 andl $0xFFFFF,%ebx 498 499 orl $0xF0000000,%ebx 500 subl %ecx,%ecx // high word must be 0 in loop for addressing 501 502 movl %ebx,C(lightdeltastep) 503 subl %ebx,%ebx // high word must be 0 in loop for addressing 504 505 Lblockloop8_mip2: 506 movl %ebp,C(lightdelta) 507 movb 2(%esi),%cl 508 509 sarl $2,%ebp 510 movb %dh,%bh 511 512 movb 3(%esi),%bl 513 addl %ebp,%edx 514 515 movb %dh,%ch 516 addl %ebp,%edx 517 518 movb 0x12345678(%ebx),%ah 519 LBPatch18: 520 movb 1(%esi),%bl 521 522 movb 0x12345678(%ecx),%al 523 LBPatch19: 524 movb (%esi),%cl 525 526 movb %dh,%bh 527 addl %ebp,%edx 528 529 rorl $16,%eax 530 movb %dh,%ch 531 532 movb 0x12345678(%ebx),%ah 533 LBPatch20: 534 movl C(lightright),%edx 535 536 movb 0x12345678(%ecx),%al 537 LBPatch21: 538 movl C(lightdelta),%ebp 539 540 movl %eax,(%edi) 541 movl C(sourcetstep),%eax 542 543 addl %eax,%esi 544 movl C(surfrowbytes),%eax 545 546 addl %eax,%edi 547 movl C(lightrightstep),%eax 548 549 addl %eax,%edx 550 movl C(lightdeltastep),%eax 551 552 addl %eax,%ebp 553 movl %edx,C(lightright) 554 555 jc Lblockloop8_mip2 556 557 // if (pbasesource >= r_sourcemax) 558 // pbasesource -= stepback; 559 560 cmpl C(r_sourcemax),%esi 561 jb LSkip_mip2 562 subl C(r_stepback),%esi 563 LSkip_mip2: 564 565 movl C(r_lightptr),%ebx 566 decl sb_v 567 568 jnz Lv_loop_mip2 569 570 popl %ebx // restore register variables 571 popl %esi 572 popl %edi 573 popl %ebp // restore the caller's stack frame 574 ret 575 576 577 //---------------------------------------------------------------------- 578 // Surface block drawer for mip level 3 579 //---------------------------------------------------------------------- 580 581 .align 4 582 .globl C(R_DrawSurfaceBlock8_mip3) 583 C(R_DrawSurfaceBlock8_mip3): 584 pushl %ebp // preserve caller's stack frame 585 pushl %edi 586 pushl %esi // preserve register variables 587 pushl %ebx 588 589 // for (v=0 ; v<numvblocks ; v++) 590 // { 591 movl C(r_lightptr),%ebx 592 movl C(r_numvblocks),%eax 593 594 movl %eax,sb_v 595 movl C(prowdestbase),%edi 596 597 movl C(pbasesource),%esi 598 599 Lv_loop_mip3: 600 601 // lightleft = lightptr[0]; 602 // lightright = lightptr[1]; 603 // lightdelta = (lightleft - lightright) & 0xFFFFF; 604 movl (%ebx),%eax // lightleft 605 movl 4(%ebx),%edx // lightright 606 607 movl %eax,%ebp 608 movl C(r_lightwidth),%ecx 609 610 movl %edx,C(lightright) 611 subl %edx,%ebp 612 613 andl $0xFFFFF,%ebp 614 leal (%ebx,%ecx,4),%ebx 615 616 movl %ebp,C(lightdelta) 617 // lightptr += lightwidth; 618 movl %ebx,C(r_lightptr) 619 620 // lightleftstep = (lightptr[0] - lightleft) >> blockdivshift; 621 // lightrightstep = (lightptr[1] - lightright) >> blockdivshift; 622 // lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) | 623 // 0xF0000000; 624 movl 4(%ebx),%ecx // lightptr[1] 625 movl (%ebx),%ebx // lightptr[0] 626 627 subl %eax,%ebx 628 subl %edx,%ecx 629 630 sarl $1,%ecx 631 632 sarl $1,%ebx 633 movl %ecx,C(lightrightstep) 634 635 subl %ecx,%ebx 636 andl $0xFFFFF,%ebx 637 638 sarl $1,%ebp 639 orl $0xF0000000,%ebx 640 641 movl %ebx,C(lightdeltastep) 642 subl %ebx,%ebx // high word must be 0 in loop for addressing 643 644 movb 1(%esi),%bl 645 subl %ecx,%ecx // high word must be 0 in loop for addressing 646 647 movb %dh,%bh 648 movb (%esi),%cl 649 650 addl %ebp,%edx 651 movb %dh,%ch 652 653 movb 0x12345678(%ebx),%al 654 LBPatch16: 655 movl C(lightright),%edx 656 657 movb %al,1(%edi) 658 movb 0x12345678(%ecx),%al 659 LBPatch17: 660 661 movb %al,(%edi) 662 movl C(sourcetstep),%eax 663 664 addl %eax,%esi 665 movl C(surfrowbytes),%eax 666 667 addl %eax,%edi 668 movl C(lightdeltastep),%eax 669 670 movl C(lightdelta),%ebp 671 movb (%esi),%cl 672 673 addl %eax,%ebp 674 movl C(lightrightstep),%eax 675 676 sarl $1,%ebp 677 addl %eax,%edx 678 679 movb %dh,%bh 680 movb 1(%esi),%bl 681 682 addl %ebp,%edx 683 movb %dh,%ch 684 685 movb 0x12345678(%ebx),%al 686 LBPatch30: 687 movl C(sourcetstep),%edx 688 689 movb %al,1(%edi) 690 movb 0x12345678(%ecx),%al 691 LBPatch31: 692 693 movb %al,(%edi) 694 movl C(surfrowbytes),%ebp 695 696 addl %edx,%esi 697 addl %ebp,%edi 698 699 // if (pbasesource >= r_sourcemax) 700 // pbasesource -= stepback; 701 702 cmpl C(r_sourcemax),%esi 703 jb LSkip_mip3 704 subl C(r_stepback),%esi 705 LSkip_mip3: 706 707 movl C(r_lightptr),%ebx 708 decl sb_v 709 710 jnz Lv_loop_mip3 711 712 popl %ebx // restore register variables 713 popl %esi 714 popl %edi 715 popl %ebp // restore the caller's stack frame 716 ret 717 718 719 .globl C(R_Surf8End) 720 C(R_Surf8End): 721 722 //---------------------------------------------------------------------- 723 // Code patching routines 724 //---------------------------------------------------------------------- 725 .data 726 727 .align 4 728 LPatchTable8: 729 .long LBPatch0-4 730 .long LBPatch1-4 731 .long LBPatch2-4 732 .long LBPatch3-4 733 .long LBPatch4-4 734 .long LBPatch5-4 735 .long LBPatch6-4 736 .long LBPatch7-4 737 .long LBPatch8-4 738 .long LBPatch9-4 739 .long LBPatch10-4 740 .long LBPatch11-4 741 .long LBPatch12-4 742 .long LBPatch13-4 743 .long LBPatch14-4 744 .long LBPatch15-4 745 .long LBPatch16-4 746 .long LBPatch17-4 747 .long LBPatch18-4 748 .long LBPatch19-4 749 .long LBPatch20-4 750 .long LBPatch21-4 751 .long LBPatch22-4 752 .long LBPatch23-4 753 .long LBPatch24-4 754 .long LBPatch25-4 755 .long LBPatch26-4 756 .long LBPatch27-4 757 .long LBPatch28-4 758 .long LBPatch29-4 759 .long LBPatch30-4 760 .long LBPatch31-4 761 762 .text 763 764 .align 4 765 .globl C(R_Surf8Patch) 766 C(R_Surf8Patch): 767 pushl %ebx 768 769 movl C(colormap),%eax 770 movl $LPatchTable8,%ebx 771 movl $32,%ecx 772 LPatchLoop8: 773 movl (%ebx),%edx 774 addl $4,%ebx 775 movl %eax,(%edx) 776 decl %ecx 777 jnz LPatchLoop8 778 779 popl %ebx 780 781 ret 782 783 #endif // id386 784