WINASM.ASM (16240B)
1 ; 2 ; Copyright 2020 Electronic Arts Inc. 3 ; 4 ; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 5 ; software: you can redistribute it and/or modify it under the terms of 6 ; the GNU General Public License as published by the Free Software Foundation, 7 ; either version 3 of the License, or (at your option) any later version. 8 9 ; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 10 ; in the hope that it will be useful, but with permitted additional restrictions 11 ; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 12 ; distributed with this program. You should have received a copy of the 13 ; GNU General Public License along with permitted additional restrictions 14 ; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>. 15 16 17 ;*************************************************************************** 18 ;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S I N C ** 19 ;*************************************************************************** 20 ;* * 21 ;* Project Name : Command & Conquer * 22 ;* * 23 ;* File Name : WINSAM.ASM * 24 ;* * 25 ;* Programmer : Steve Tall * 26 ;* * 27 ;* Start Date : October 26th, 1995 * 28 ;* * 29 ;* Last Update : October 26th, 1995 [ST] * 30 ;* * 31 ;*-------------------------------------------------------------------------* 32 ;* Functions: * 33 ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * 34 35 36 IDEAL 37 P386 38 MODEL USE32 FLAT 39 40 global C _AbortModemFunctionPtr:dword 41 global C Memory_Error_Exit :dword 42 global C MouseQX :dword 43 global C MouseQY :dword 44 45 global FastGetPortHardware_ :near 46 global FastSetPortHardware_ :near 47 global PortOpenGreenleafFast_ :near 48 global HMWaitForOK_ :near 49 global HMSetDialingMethod_ :near 50 global HMDial_ :near 51 global HMInputLine_ :near 52 global HMAnswer_ :near 53 global PortKillTime_ :near 54 global HMSendStringNoWait_ :near 55 global HMSetUpEchoRoutine_ :near 56 global HMSetUpAbortKey_ :near 57 global SetAbortModemFunctionPtr_:near 58 global Change8259Priority_ :near 59 global HMSendString_ :near 60 global C Stop_Execution :near 61 62 63 global _IPX_Initialise:near 64 global _ASM_IPX_Initialise:near 65 66 67 codeseg 68 69 proc _ASM_IPX_Initialise near 70 71 int 3 72 jmp _IPX_Initialise 73 74 endp 75 76 77 78 79 global _Int3:near 80 proc _Int3 near 81 ;int 3 82 ret 83 endp 84 85 86 proc Stop_Execution C near 87 88 nop 89 ret 90 91 endp 92 93 94 95 ; 96 ; Stuff needed from the shape library 97 ; 98 ; 99 ; 100 101 102 INCLUDE "shape.inc" 103 104 105 106 107 ;*************************************************************************** 108 ;* ModeX_Blit -- Copy a 320x200 graphic view port to a modex screen * 109 ;* * 110 ;* * 111 ;* INPUT: eax - graphic view port * 112 ;* * 113 ;* OUTPUT: none * 114 ;* * 115 ;* PROTO: extern "C" void ModeX_Blit (GraphicBufferClass *source); * 116 ;* * 117 ;* HISTORY: * 118 ;* 10/26/1994 PWG : Created. * 119 ;*=========================================================================* 120 121 SEQUENCER =3c4h ; sequencer port 122 MAP_MASK =2 ; map mask register 123 124 INCLUDE "gbuffer.inc" 125 global ModeX_Blit_:near 126 127 128 proc ModeX_Blit_ NEAR 129 130 pushad 131 mov ebx,eax 132 133 mov esi,[(GraphicViewPort ebx).GVPOffset] 134 mov eax,[(GraphicViewPort ebx).GVPXAdd] 135 add eax,[(GraphicViewPort ebx).GVPPitch] 136 mov edi,0a0000h 137 mov ebx,eax 138 139 mov al,MAP_MASK 140 141 mov ebp,200 142 143 ??each_line_lp: mov ah,1 ;1st plane 144 push ebx 145 push esi 146 147 ??each_plane_lp:mov edx,SEQUENCER 148 out dx,ax 149 150 push esi 151 push edi 152 push eax 153 154 rept 10 155 mov al,[esi] 156 mov bl,[esi+8] 157 mov cl,[esi+16] 158 mov dl,[esi+24] 159 mov ah,[esi+4] 160 mov bh,[esi+12] 161 mov ch,[esi+20] 162 mov dh,[esi+28] 163 shl ebx,16 164 shl edx,16 165 or ebx,eax 166 or edx,ecx 167 mov [edi],ebx 168 mov [edi+4],edx 169 add esi,32 170 add edi,8 171 endm 172 173 pop eax 174 pop edi 175 pop esi 176 inc esi 177 shl ah,1 178 cmp ah,16 179 jl ??each_plane_lp 180 181 182 pop esi 183 pop ebx 184 lea esi,[esi+ebx+320] 185 add edi,80 186 dec ebp 187 jnz ??each_line_lp 188 189 popad 190 191 ret 192 193 endp ModeX_Blit_ 194 195 196 197 198 199 200 ifdef cuts 201 pushad 202 mov ebx,eax 203 204 mov esi,[(GraphicViewPort ebx).GVPOffset] 205 mov eax,[(GraphicViewPort ebx).GVPXAdd] 206 add eax,[(GraphicViewPort ebx).GVPPitch] 207 mov edi,0a0000h 208 mov ebx,eax 209 210 mov al,MAP_MASK 211 mov ah,1 ;1st plane 212 213 ??each_plane_lp:mov edx,SEQUENCER 214 out dx,ax 215 mov ebp,200 ;do 200 lines 216 push esi 217 push edi 218 219 ??each_line_lp: mov ecx,320/4 220 221 ??each_pixel_lp:mov dl,[esi] 222 mov [edi],dl 223 add esi,4 224 inc edi 225 dec ecx 226 jnz ??each_pixel_lp 227 228 add esi,ebx 229 dec ebp 230 jnz ??each_line_lp 231 232 pop edi 233 pop esi 234 inc esi 235 shl ah,1 236 237 cmp ah,16 238 jl ??each_plane_lp 239 endif 240 241 242 243 244 245 246 247 248 249 250 proc FastGetPortHardware_ NEAR 251 endp 252 253 proc FastSetPortHardware_ NEAR 254 endp 255 256 proc PortOpenGreenleafFast_ NEAR 257 endp 258 259 proc HMWaitForOK_ NEAR 260 endp 261 262 proc HMSetDialingMethod_ NEAR 263 endp 264 265 proc HMDial_ NEAR 266 endp 267 268 proc HMInputLine_ NEAR 269 endp 270 271 proc HMAnswer_ NEAR 272 endp 273 274 proc PortKillTime_ NEAR 275 endp 276 277 proc HMSendStringNoWait_ NEAR 278 endp 279 280 proc HMSetUpEchoRoutine_ NEAR 281 endp 282 283 proc HMSetUpAbortKey_ NEAR 284 endp 285 286 proc SetAbortModemFunctionPtr_ NEAR 287 endp 288 289 proc Change8259Priority_ NEAR 290 endp 291 292 proc HMSendString_ NEAR 293 endp 294 295 ret 296 297 298 299 300 301 302 303 masm 304 ; 305 ; Change a DAC colour register directly 306 ; 307 ; register number in al 308 ; 309 ; bh=red bl=green cl=blue 310 ; 311 312 set_dac_col proc near 313 pushad 314 cli 315 push eax 316 mov dx,03dah 317 in al,dx 318 jmp @@1 319 @@1: mov dx,03c8h 320 pop eax 321 out dx,al 322 jmp @@2 323 @@2: inc dl 324 mov al,bh 325 out dx,al 326 jmp @@3 327 @@3: mov al,bl 328 out dx,al 329 jmp @@4 330 @@4: mov al,cl 331 out dx,al 332 jmp @@5 333 @@5: sti 334 popad 335 ret 336 set_dac_col endp 337 338 ideal 339 340 341 global Set_Palette_Register_:near 342 343 344 proc Set_Palette_Register_ near 345 346 pushad 347 and cl,63 348 mov bh,dl 349 and bh,63 350 and bl,63 351 call set_dac_col 352 popad 353 ret 354 355 endp Set_Palette_Register_ 356 357 358 359 360 locals ?? 361 362 363 364 ends 365 366 dataseg 367 368 LineBuffer dd 640 dup (?) 369 ends 370 371 372 373 segment mycode page public use32 'code' ; Need stricter segment alignment 374 375 global C Asm_Interpolate:near 376 global C Asm_Interpolate_Line_Double:near 377 global C Asm_Interpolate_Line_Interpolate:near 378 global C PaletteInterpolationTable:byte 379 380 381 ;********************************************************************************************* 382 ;* Asm_Interpolate -- interpolate a 320x200 buffer to a 640x400 screen * 383 ;* * 384 ;* INPUT: ptr to source buffer (320x200 image) * 385 ;* ptr to dest buffer (640x400) * 386 ;* height of source buffer * 387 ;* width of source buffer * 388 ;* width of dest buffer * 389 ;* * 390 ;* * 391 ;* OUTPUT: none * 392 ;* * 393 ;* Warnings: * 394 ;* * 395 ;* HISTORY: * 396 ;* 12/15/95 ST : Created. * 397 ;*===========================================================================================* 398 399 PROC Asm_Interpolate C near 400 401 ARG src_ptr:dword 402 ARG dest_ptr:dword 403 ARG source_height:dword 404 ARG source_width:dword 405 ARG dest_width:dword 406 407 LOCAL old_dest:dword 408 409 pushad 410 411 mov eax,[dest_ptr] 412 mov [old_dest],eax 413 414 mov esi,[src_ptr] 415 416 ??each_line_loop: 417 mov ecx,[source_width] 418 sub ecx,2 419 shr ecx,1 420 mov edi,[old_dest] 421 jmp ??interpolate_loop 422 423 align 32 424 ; 425 ; convert 2 pixels of source into 4 pixels of destination 426 ; so we can write to video memory with dwords 427 ; 428 ??interpolate_loop: 429 mov eax,[esi] 430 lea esi,[esi+2] 431 mov edx,eax 432 mov ebx,eax 433 and edx,65535 434 ror ebx,8 435 mov bl,[edx+PaletteInterpolationTable] 436 mov bh,ah 437 and eax,000ffff00h 438 ror ebx,8 439 440 ;1st 3 pixels now in ebx 441 442 shr eax,8 443 mov bh,[eax+PaletteInterpolationTable] 444 ror ebx,16 445 mov [edi],ebx 446 add edi,4 447 448 dec ecx 449 jnz ??interpolate_loop 450 451 ; do the last three pixels and a blank on the end of a row 452 xor eax,eax 453 mov ax,[esi] 454 mov [edi],al 455 inc edi 456 lea esi,[esi+2] 457 mov al,[eax+PaletteInterpolationTable] 458 mov [edi],al 459 inc edi 460 mov [edi],ah 461 inc edi 462 mov [byte edi],0 463 464 mov edi,[dest_width] 465 add [old_dest],edi 466 467 dec [source_height] 468 jnz ??each_line_loop 469 470 popad 471 ret 472 473 endp Asm_Interpolate 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 PROC Asm_Interpolate_Line_Double C near 489 ARG src_ptr:dword 490 ARG dest_ptr:dword 491 ARG source_height:dword 492 ARG source_width:dword 493 ARG dest_width:dword 494 495 LOCAL old_dest:dword 496 LOCAL width_counter:dword 497 LOCAL pixel_count:dword 498 499 pushad 500 501 mov eax,[dest_ptr] 502 mov [old_dest],eax 503 504 mov esi,[src_ptr] 505 mov edi,[dest_ptr] 506 507 ??each_line_loop: 508 mov [width_counter],0 509 mov ecx,[source_width] 510 sub ecx,2 511 shr ecx,1 512 mov [pixel_count],ecx 513 mov ecx,offset LineBuffer 514 mov edi,[old_dest] 515 jmp ??interpolate_loop 516 align 16 517 518 ; convert 2 pixels of source into 4 pixels of destination 519 ??interpolate_loop: 520 mov eax,[esi] 521 lea esi,[esi+2] 522 mov edx,eax 523 mov ebx,eax 524 and edx,65535 525 ror ebx,8 526 mov bl,[edx+PaletteInterpolationTable] 527 mov bh,ah 528 and eax,000ffff00h 529 ror ebx,8 530 531 ;1st 3 pixels now in ebx 532 shr eax,8 533 mov bh,[eax+PaletteInterpolationTable] 534 ror ebx,16 535 mov [edi],ebx 536 mov [ecx],ebx 537 add edi,4 538 add ecx,4 539 540 dec [pixel_count] 541 jnz ??interpolate_loop 542 543 ; do the last three pixels and a blank 544 545 xor eax,eax 546 mov ax,[esi] 547 mov [edi],al 548 mov [ecx],al 549 inc edi 550 inc ecx 551 lea esi,[esi+2] 552 mov al,[eax+PaletteInterpolationTable] 553 mov [edi],al 554 mov [ecx],al 555 inc edi 556 inc ecx 557 mov [edi],ah 558 mov [ecx],ah 559 inc edi 560 inc ecx 561 mov [byte edi],0 562 mov [byte ecx],0 563 564 mov edi,[dest_width] 565 shr edi,1 566 add [old_dest],edi 567 push esi 568 push edi 569 mov esi,offset LineBuffer 570 mov edi,[old_dest] 571 mov ecx,[source_width] 572 shr ecx,1 573 rep movsd 574 pop edi 575 pop esi 576 add [old_dest],edi 577 mov edi,[old_dest] 578 579 dec [source_height] 580 jnz ??each_line_loop 581 582 popad 583 ret 584 585 endp Asm_Interpolate_Line_Double 586 587 588 589 590 591 592 593 594 595 ends 596 597 dataseg 598 599 TopLine dd 640 dup (?) 600 BottomLine dd 640 dup (?) 601 602 603 segment mycode page public use32 'code' ; Need stricter segment alignment 604 605 606 proc Interpolate_Single_Line C near 607 608 ARG source_ptr:dword 609 ARG dest_ptr:dword 610 ARG source_width:dword 611 612 pushad 613 614 mov ecx,[source_width] 615 sub ecx,2 616 shr ecx,1 617 618 mov esi,[source_ptr] 619 mov edi,[dest_ptr] 620 621 ??interpolate_loop: 622 mov eax,[esi] 623 lea esi,[esi+2] 624 mov edx,eax 625 mov ebx,eax 626 and edx,65535 627 ror ebx,8 628 mov bl,[edx+PaletteInterpolationTable] 629 mov bh,ah 630 and eax,000ffff00h 631 ror ebx,8 632 633 ;1st 3 pixels now in ebx 634 shr eax,8 635 mov bh,[eax+PaletteInterpolationTable] 636 ror ebx,16 637 mov [edi],ebx 638 add edi,4 639 640 dec ecx 641 jnz ??interpolate_loop 642 643 ; do the last three pixels and a blank 644 645 xor eax,eax 646 mov ax,[esi] 647 mov [edi],al 648 inc edi 649 mov al,[eax+PaletteInterpolationTable] 650 mov [edi],al 651 inc edi 652 mov [edi],ah 653 inc edi 654 mov [byte edi],0 655 656 popad 657 ret 658 659 660 endp Interpolate_Single_Line 661 662 663 proc Interpolate_Between_Lines C near 664 665 ARG source1:dword 666 ARG source2:dword 667 ARG destination:dword 668 ARG source_width:dword 669 670 pushad 671 mov esi,[source1] 672 mov edi,[destination] 673 mov ebx,[source2] 674 xor eax,eax 675 mov ecx,[source_width] 676 add ecx,ecx 677 678 ??interpolate_each_pixel_loop: 679 mov al,[esi] 680 mov ah,[ebx] 681 inc esi 682 inc ebx 683 mov dl,[eax+PaletteInterpolationTable] 684 mov [edi],dl 685 inc edi 686 dec ecx 687 jnz ??interpolate_each_pixel_loop 688 689 popad 690 ret 691 692 endp Interpolate_Between_Lines 693 694 695 696 697 macro Lineswp 698 push [next_line] 699 push [last_line] 700 pop [next_line] 701 pop [last_line] 702 endm 703 704 705 PROC Asm_Interpolate_Line_Interpolate C near 706 707 708 ARG src_ptr:dword 709 ARG dest_ptr:dword 710 ARG source_lines:dword 711 ARG source_width:dword 712 ARG dest_width:dword 713 714 LOCAL old_dest:dword 715 LOCAL pixel_count:dword 716 LOCAL next_line:dword 717 LOCAL last_line:dword 718 719 pushad 720 721 mov eax,[dest_ptr] 722 mov [old_dest],eax 723 724 mov [next_line],offset TopLine 725 mov [last_line],offset BottomLine 726 mov ecx,[source_width] 727 shr ecx,1 728 mov [pixel_count],ecx 729 shr [dest_width],1 730 731 call Interpolate_Single_Line C,[src_ptr],[next_line],[source_width] 732 mov esi,[source_width] 733 Lineswp 734 add [src_ptr],esi 735 dec [source_lines] 736 737 738 ??each_line_pair_loop: 739 call Interpolate_Single_Line C,[src_ptr],[next_line],[source_width] 740 call Interpolate_Between_Lines C,[last_line],[next_line],offset LineBuffer,[source_width] 741 742 mov esi,[last_line] 743 mov edi,[old_dest] 744 mov ecx,[pixel_count] 745 rep movsd 746 747 mov edi,[old_dest] 748 mov esi,offset LineBuffer 749 add edi,[dest_width] 750 mov ecx,[pixel_count] 751 mov [old_dest],edi 752 rep movsd 753 754 mov edi,[old_dest] 755 mov esi,[source_width] 756 add edi,[dest_width] 757 add [src_ptr],esi 758 mov [old_dest],edi 759 760 Lineswp 761 dec [source_lines] 762 jnz ??each_line_pair_loop 763 764 call Interpolate_Single_Line C,[src_ptr],[next_line],[source_width] 765 mov esi,[next_line] 766 mov edi,[old_dest] 767 mov ecx,[pixel_count] 768 rep movsd 769 770 popad 771 ret 772 773 774 endp Asm_Interpolate_Line_Interpolate 775 776 ends mycode 777 778 779 780 781 global C Asm_Create_Palette_Interpolation_Table:near 782 global C InterpolationPalette:dword 783 784 codeseg 785 786 787 proc Asm_Create_Palette_Interpolation_Table C near 788 789 LOCAL palette_counter:dword 790 LOCAL first_palette:dword 791 LOCAL second_palette:dword 792 LOCAL dest_ptr:dword 793 LOCAL count:dword 794 LOCAL closest_colour:dword 795 LOCAL distance_of_closest:dword 796 797 pushad 798 799 mov [dest_ptr],0 800 mov [palette_counter],256 801 mov esi,[InterpolationPalette] 802 803 ??palette_outer_loop: 804 mov edi,[InterpolationPalette] 805 mov ecx,256 806 807 ??palette_inner_loop: 808 mov bl,[esi] 809 add bl,[edi] 810 shr bl,1 811 812 mov bh,[esi+1] 813 add bh,[edi+1] 814 shr bh,1 815 816 mov dl,[esi+2] 817 add dl,[edi+2] 818 shr dl,1 819 820 mov [closest_colour],0 821 mov [distance_of_closest],-1 822 823 push edi 824 push ecx 825 mov edi,[InterpolationPalette] 826 mov [count],0 827 828 ??cmp_pal_lp: xor eax,eax 829 xor ecx,ecx 830 mov al,[edi] 831 sub al,bl 832 imul al 833 mov ecx,eax 834 mov al,[edi+1] 835 sub al,bh 836 imul al 837 add ecx,eax 838 mov al,[edi+2] 839 sub al,dl 840 imul al 841 add ecx,eax 842 843 cmp ecx,[distance_of_closest] 844 ja ??end_cmp_lp 845 mov [distance_of_closest],ecx 846 mov eax,[count] 847 mov [closest_colour],eax 848 test ecx,ecx 849 jz ??got_perfect 850 851 ??end_cmp_lp: lea edi,[edi+3] 852 inc [count] 853 cmp [count],256 854 jb ??cmp_pal_lp 855 856 857 ??got_perfect: mov edi,[dest_ptr] 858 mov eax,[closest_colour] 859 mov [edi+PaletteInterpolationTable],al 860 inc [dest_ptr] 861 862 pop ecx 863 pop edi 864 lea edi,[edi+3] 865 dec ecx 866 jnz ??palette_inner_loop 867 868 lea esi,[esi+3] 869 dec [palette_counter] 870 jnz ??palette_outer_loop 871 872 popad 873 ret 874 875 endp Asm_Create_Palette_Interpolation_Table 876 877 878 879 880 DATASEG 881 882 _AbortModemFunctionPtr dd 0 883 Memory_Error_Exit dd 0 884 MouseQX dd 0 885 MouseQY dd 0 886 887 end