1; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX 2; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO 3; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A 4; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS 5; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS 6; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE 7; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE 8; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS 9; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. 10; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. 11 12.386 13 14_DATA SEGMENT BYTE PUBLIC USE32 'DATA' 15 16INCLUDE psmacros.inc 17INCLUDE TWEAK.INC 18INCLUDE VGAREGS.INC 19 20extd _gr_var_bwidth 21 22extd _modex_line_vertincr 23extd _modex_line_incr1 24extd _modex_line_incr2 25 _modex_line_routine dd ? 26extd _modex_line_x1 27extd _modex_line_y1 28extd _modex_line_x2 29extd _modex_line_y2 30extb _modex_line_Color 31 32 SavedColor db ? 33 34LEFT_MASK1 = 1000b 35LEFT_MASK2 = 1100b 36LEFT_MASK3 = 1110b 37RIGHT_MASK1 = 0001b 38RIGHT_MASK2 = 0011b 39RIGHT_MASK3 = 0111b 40ALL_MASK = 1111b 41 42tmppal db 768 dup (0) 43fb_pal dd ? 44fb_add dw ? 45fb_count dd ? 46 47MaskTable1 db ALL_MASK AND RIGHT_MASK1, 48 ALL_MASK AND RIGHT_MASK2, 49 ALL_MASK AND RIGHT_MASK3, 50 ALL_MASK, 51 LEFT_MASK3 AND RIGHT_MASK1, 52 LEFT_MASK3 AND RIGHT_MASK2, 53 LEFT_MASK3 AND RIGHT_MASK3, 54 LEFT_MASK3, 55 LEFT_MASK2 AND RIGHT_MASK1, 56 LEFT_MASK2 AND RIGHT_MASK2, 57 LEFT_MASK2 AND RIGHT_MASK3, 58 LEFT_MASK2, 59 LEFT_MASK1 AND RIGHT_MASK1, 60 LEFT_MASK1 AND RIGHT_MASK2, 61 LEFT_MASK1 AND RIGHT_MASK3, 62 LEFT_MASK1, 63 64MaskTable2 db ALL_MASK,RIGHT_MASK1, 65 ALL_MASK,RIGHT_MASK2, 66 ALL_MASK,RIGHT_MASK3, 67 ALL_MASK,ALL_MASK, 68 LEFT_MASK3,RIGHT_MASK1, 69 LEFT_MASK3,RIGHT_MASK2, 70 LEFT_MASK3,RIGHT_MASK3, 71 LEFT_MASK3,ALL_MASK, 72 LEFT_MASK2,RIGHT_MASK1, 73 LEFT_MASK2,RIGHT_MASK2, 74 LEFT_MASK2,RIGHT_MASK3, 75 LEFT_MASK2,ALL_MASK, 76 LEFT_MASK1,RIGHT_MASK1, 77 LEFT_MASK1,RIGHT_MASK2, 78 LEFT_MASK1,RIGHT_MASK3, 79 LEFT_MASK1,ALL_MASK 80 81DrawTable dd DrawMR, 82 DrawMR, 83 DrawMR, 84 DrawM, 85 DrawLMR, 86 DrawLMR, 87 DrawLMR, 88 DrawLM, 89 DrawLMR, 90 DrawLMR, 91 DrawLMR, 92 DrawLM, 93 DrawLMR, 94 DrawLMR, 95 DrawLMR, 96 DrawLM 97 98_DATA ENDS 99 100DGROUP GROUP _DATA 101 102 103_TEXT SEGMENT BYTE PUBLIC USE32 'CODE' 104 105 ASSUME DS:_DATA 106 ASSUME CS:_TEXT 107 108PUBLIC gr_sync_display_ 109 110gr_sync_display_: 111 112 push ax 113 push dx 114 mov dx, VERT_RESCAN 115VS2A: in al, dx 116 and al, 08h 117 jnz VS2A ; Loop until not in vertical retrace 118VS2B: in al, dx 119 and al, 08h 120 jz VS2B ; Loop until in vertical retrace 121 122 pop dx 123 pop ax 124 ret 125 126 127PUBLIC gr_modex_uscanline_ 128 129gr_modex_uscanline_: 130 push edi 131 132 ; EAX = X1 (X1 and X2 don't need to be sorted) 133 ; EDX = X2 134 ; EBX = Y 135 ; ECX = Color 136 137 mov SavedColor, cl 138 139 ;mov ebx, _RowOffset[ebx*4] 140 mov edi, _gr_var_bwidth 141 imul edi, ebx 142 add edi, 0A0000h 143 cmp eax, edx 144 jle @f 145 xchg eax, edx 146@@: mov bl, al 147 shl bl, 2 148 mov bh, dl 149 and bh, 011b 150 or bl, bh 151 and ebx, 0fh 152 ; BX = LeftRight switch command. (4bit) 153 shr eax, 2 154 shr edx, 2 155 add edi, eax 156 ; EDI = Offset into video memory 157 mov ecx, edx 158 sub ecx, eax 159 ; ECX = X2/4 - X1/4 - 1 160 jnz LargerThan4 161 162;======================= ONE GROUP OF 4 OR LESS TO DRAW ==================== 163 164 mov dx, SC_INDEX 165 mov al, SC_MAP_MASK 166 out dx, al 167 inc dx 168 mov al, MaskTable1[ebx] 169 out dx, al 170 mov al, SavedColor 171 mov [edi], al ; Write the one pixel 172 pop edi 173 ret 174 175LargerThan4: 176 dec ecx 177 jnz LargerThan8 178 179;===================== TWO GROUPS OF 4 OR LESS TO DRAW ==================== 180 181 mov cx, WORD PTR MaskTable2[ebx*2] 182 mov bl, SavedColor 183 mov dx, SC_INDEX 184 mov al, SC_MAP_MASK 185 out dx, al 186 inc dx 187 mov al, cl 188 out dx, al 189 mov [edi], bl ; Write the left pixel 190 mov al, ch 191 out dx, al 192 mov [edi+1], bl ; Write the right pixel 193 pop edi 194 ret 195 196;========================= MANY GROUPS OF 4 TO DRAW ====================== 197LargerThan8: 198 mov dx, SC_INDEX 199 mov al, SC_MAP_MASK 200 out dx, al 201 inc dx 202 ; DX = SC_INDEX 203 mov al, SavedColor 204 mov ah, al 205 ; AL,AH = color of pixel 206 jmp NEAR32 PTR DrawTable[ebx*4] 207 208 209DrawM: ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index 210 mov al, ALL_MASK 211 out dx, al 212 mov al, ah 213 cld 214 add ecx, 2 215 shr ecx, 1 216 rep stosw ; Write the middle pixels 217 jnc @F 218 stosb ; Write the middle odd pixel 219@@: pop edi 220 ret 221 222DrawLM: 223 ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index 224 mov al, BYTE PTR MaskTable2[ebx*2] 225 out dx, al 226 mov [edi], ah ; Write leftmost pixels 227 inc edi 228 mov al, ALL_MASK 229 out dx, al 230 mov al, ah 231 cld 232 inc ecx 233 shr ecx, 1 234 rep stosw ; Write the middle pixels 235 jnc @F 236 stosb ; Write the middle odd pixel 237@@: pop edi 238 ret 239 240 241DrawLMR: ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index 242 mov bx, WORD PTR MaskTable2[ebx*2] 243 mov al, bl 244 out dx, al 245 mov [edi], ah ; Write leftmost pixels 246 inc edi 247 mov al, ALL_MASK 248 out dx, al 249 mov al, ah 250 cld 251 shr ecx, 1 252 rep stosw ; Write the middle pixels 253 jnc @F 254 stosb ; Write the middle odd pixel 255@@: mov al, bh 256 out dx, al 257 mov [edi], ah ; Write the rightmost pixels 258 pop edi 259 ret 260 261DrawMR: ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index 262 mov bx, WORD PTR MaskTable2[ebx*2] 263 mov al, ALL_MASK 264 out dx, al 265 mov al, ah 266 cld 267 inc ecx 268 shr ecx, 1 269 rep stosw ; Write the middle pixels 270 jnc @F 271 stosb ; Write the middle odd pixel 272@@: mov al, bh 273 out dx, al 274 mov [edi], ah ; Write the rightmost pixels 275 pop edi 276 ret 277 278 279PUBLIC gr_modex_setmode_ 280 281gr_modex_setmode_: 282 283 push ebx 284 push ecx 285 push edx 286 push esi 287 push edi 288 289 mov ecx, eax 290 dec ecx 291 292 cmp ecx, LAST_X_MODE 293 jbe @f 294 mov ecx, 0 295@@: 296 297 ;call turn_screen_off 298 299 push ecx ; some bios's dont preserve cx 300 301 ;mov ax, 1201h 302 ;mov bl, 31h ; disable palette loading at mode switch 303 ;int 10h 304 mov ax,13h ; let the BIOS set standard 256-color 305 int 10h ; mode (320x200 linear) 306 ;mov ax, 1200h 307 ;mov bl, 31h ; enable palette loading at mode switch 308 ;int 10h 309 310 pop ecx 311 312 mov dx,SC_INDEX 313 mov ax,0604h 314 out dx,ax ; disable chain4 mode 315 316 mov dx,SC_INDEX 317 mov ax,0100h 318 out dx,ax ; synchronous reset while setting Misc 319 ; Output for safety, even though clock 320 ; unchanged 321 322 mov esi, dword ptr ModeTable[ecx*4] 323 lodsb 324 325 or al,al 326 jz DontSetDot 327 328 mov dx,MISC_OUTPUT 329 out dx,al ; select the dot clock and Horiz 330 ; scanning rate 331 332 ;mov dx,SC_INDEX 333 ;mov al,01h 334 ;out dx,al 335 ;inc dx 336 ;in al, dx 337 ;or al, 1000b 338 ;out dx, al 339 340DontSetDot: 341 mov dx,SC_INDEX 342 mov ax,0300h 343 out dx,ax ; undo reset (restart sequencer) 344 345 mov dx,CRTC_INDEX ; reprogram the CRT Controller 346 mov al,11h ; VSync End reg contains register write 347 out dx,al ; protect bit 348 inc dx ; CRT Controller Data register 349 in al,dx ; get current VSync End register setting 350 and al,07fh ; remove write protect on various 351 out dx,al ; CRTC registers 352 dec dx ; CRT Controller Index 353 cld 354 xor ecx,ecx 355 lodsb 356 mov cl,al 357 358SetCRTParmsLoop: 359 lodsw ; get the next CRT Index/Data pair 360 out dx,ax ; set the next CRT Index/Data pair 361 loop SetCRTParmsLoop 362 363 mov dx,SC_INDEX 364 mov ax,0f02h 365 out dx,ax ; enable writes to all four planes 366 mov edi, 0A0000h ; point ES:DI to display memory 367 xor ax,ax ; clear to zero-value pixels 368 mov ecx,8000h ; # of words in display memory 369 rep stosw ; clear all of display memory 370 371 ; Set pysical screen dimensions 372 373 xor eax, eax 374 lodsw ; Load scrn pixel width 375 mov cx, ax 376 shl eax, 16 377 378 mov dx,CRTC_INDEX 379 mov al,CRTC_OFFSET 380 out dx,al 381 inc dx 382 mov ax,cx 383 shr ax,3 384 out dx,al 385 386 ;mov si, 360 387 ;@@: 388 ;mov ax, 04f06h 389 ;mov bl, 0 390 ;mov cx, si 391 ;int 10h 392 ;cmp cx, si 393 ;je @f 394 ;inc si 395 ;jmp @B 396 ;@@: 397 ;movzx eax, si 398 399 lodsw ; Load Screen Phys. Height 400 401 ;call turn_screen_on 402 403 pop edi 404 pop esi 405 pop edx 406 pop ecx 407 pop ebx 408 409 ret 410 411PUBLIC gr_modex_setplane_ 412 413gr_modex_setplane_: 414 415 push cx 416 push dx 417 418 mov cl, al 419 420 ; SELECT WRITE PLANE 421 and cl,011b ;CL = plane 422 mov ax,0100h + MAP_MASK ;AL = index in SC of Map Mask reg 423 shl ah,cl ;set only the bit for the required 424 ; plane to 1 425 mov dx,SC_INDEX ;set the Map Mask to enable only the 426 out dx,ax ; pixel's plane 427 428 ; SELECT READ PLANE 429 mov ah,cl ;AH = plane 430 mov al,READ_MAP ;AL = index in GC of the Read Map reg 431 mov dx,GC_INDEX ;set the Read Map to read the pixel's 432 out dx,ax ; plane 433 434 pop dx 435 pop cx 436 437 ret 438 439PUBLIC gr_modex_setstart_ 440 441gr_modex_setstart_: 442 443 ; EAX = X 444 ; EDX = Y 445 ; EBX = Wait for retrace 446 447 push ebx 448 push ecx 449 push ebx 450 451 mov ecx, _gr_var_bwidth 452 imul ecx, edx 453 454 shr eax, 2 455 add eax, ecx 456 457 mov ch, ah 458 mov bh, al 459 460 mov bl, CC_START_LO 461 mov cl, CC_START_HI 462 463 cli 464 mov dx, VERT_RESCAN 465WaitDE: in al, dx 466 test al, 01h 467 jnz WaitDE 468 469 mov dx, CRTC_INDEX 470 mov ax, bx 471 out dx, ax ; Start address low 472 mov ax, cx 473 out dx, ax ; Start address high 474 sti 475 476 pop ebx 477 cmp ebx, 0 478 je NoWaitVS 479 mov dx, VERT_RESCAN 480WaitVS: in al, dx 481 test al, 08h 482 jz WaitVS ; Loop until in vertical retrace 483NoWaitVS: 484 485 pop ecx 486 pop ebx 487 488 ret 489 490 491 492 493ModeXAddr macro 494; given: ebx=x, eax=y, return cl=plane mask, ebx=address, trash eax 495 mov cl, bl 496 and cl, 3 497 shr ebx, 2 498 imul eax, _gr_var_bwidth 499 add ebx, eax 500 add ebx, 0A0000h 501 endm 502 503 504;----------------------------------------------------------------------- 505; 506; Line drawing function for all MODE X 256 Color resolutions 507; Based on code from "PC and PS/2 Video Systems" by Richard Wilton. 508 509PUBLIC gr_modex_line_ 510 511gr_modex_line_: 512 pusha 513 514 mov dx,SC_INDEX ; setup for plane mask access 515 516; check for vertical line 517 518 mov esi,_gr_var_bwidth 519 mov ecx,_modex_line_x2 520 sub ecx,_modex_line_x1 521 jz VertLine 522 523; force x1 < x2 524 525 jns L01 526 527 neg ecx 528 529 mov ebx,_modex_line_x2 530 xchg ebx,_modex_line_x1 531 mov _modex_line_x2,ebx 532 533 mov ebx,_modex_line_y2 534 xchg ebx,_modex_line_y1 535 mov _modex_line_y2,ebx 536 537; calc dy = abs(y2 - y1) 538 539L01: 540 mov ebx,_modex_line_y2 541 sub ebx,_modex_line_y1 542 jnz short skip 543 jmp HorizLine 544skip: jns L03 545 546 neg ebx 547 neg esi 548 549; select appropriate routine for slope of line 550 551L03: 552 mov _modex_line_vertincr,esi 553 mov _modex_line_routine,offset LoSlopeLine 554 cmp ebx,ecx 555 jle L04 556 mov _modex_line_routine,offset HiSlopeLine 557 xchg ebx,ecx 558 559; calc initial decision variable and increments 560 561L04: 562 shl ebx,1 563 mov _modex_line_incr1,ebx 564 sub ebx,ecx 565 mov esi,ebx 566 sub ebx,ecx 567 mov _modex_line_incr2,ebx 568 569; calc first pixel address 570 571 push ecx 572 mov eax,_modex_line_y1 573 mov ebx,_modex_line_x1 574 ModeXAddr 575 mov edi,ebx 576 mov al,1 577 shl al,cl 578 mov ah,al ; duplicate nybble 579 shl al,4 580 add ah,al 581 mov bl,ah 582 pop ecx 583 inc ecx 584 jmp [_modex_line_routine] 585 586; routine for verticle lines 587 588VertLine: 589 mov eax,_modex_line_y1 590 mov ebx,_modex_line_y2 591 mov ecx,ebx 592 sub ecx,eax 593 jge L31 594 neg ecx 595 mov eax,ebx 596 597L31: 598 inc ecx 599 mov ebx,_modex_line_x1 600 push ecx 601 ModeXAddr 602 603 mov ah,1 604 shl ah,cl 605 mov al,MAP_MASK 606 out dx,ax 607 pop ecx 608 mov ax, word ptr _modex_line_Color 609 610; draw the line 611 612L32: 613 mov [ebx],al 614 add ebx,esi 615 loop L32 616 jmp Lexit 617 618; routine for horizontal line 619 620HorizLine: 621 622 mov eax,_modex_line_y1 623 mov ebx,_modex_line_x1 624 ModeXAddr 625 626 mov edi,ebx ; set dl = first byte mask 627 mov dl,00fh 628 shl dl,cl 629 630 mov ecx,_modex_line_x2 ; set dh = last byte mask 631 and cl,3 632 mov dh,00eh 633 shl dh,cl 634 not dh 635 636; determine byte offset of first and last pixel in line 637 638 mov eax,_modex_line_x2 639 mov ebx,_modex_line_x1 640 641 shr eax,2 ; set ax = last byte column 642 shr ebx,2 ; set bx = first byte column 643 mov ecx,eax ; cx = ax - bx 644 sub ecx,ebx 645 646 mov eax,edx ; mov end byte masks to ax 647 mov dx,SC_INDEX ; setup dx for VGA outs 648 mov bl,_modex_line_Color 649 650; set pixels in leftmost byte of line 651 652 or ecx,ecx ; is start and end pt in same byte 653 jnz L42 ; no ! 654 and ah,al ; combine start and end masks 655 jmp short L44 656 657L42: push eax 658 mov ah,al 659 mov al,MAP_MASK 660 out dx,ax 661 mov al,bl 662 stosb 663 dec ecx 664 665; draw remainder of the line 666 667L43: 668 mov ah,0Fh 669 mov al,MAP_MASK 670 out dx,ax 671 mov al,bl 672 rep stosb 673 pop eax 674 675; set pixels in rightmost byte of line 676 677L44: 678 mov al,MAP_MASK 679 out dx, ax 680 mov byte ptr [edi],bl 681 jmp Lexit 682 683 684; routine for dy >= dx (slope <= 1) 685 686LoSlopeLine: 687 mov al,MAP_MASK 688 mov bh,byte ptr _modex_line_Color 689L10: 690 mov ah,bl 691 692L11: 693 or ah,bl 694 rol bl,1 695 jc L14 696 697; bit mask not shifted out 698 699 or esi,esi 700 jns L12 701 add esi,_modex_line_incr1 702 loop L11 703 704 out dx,ax 705 mov [edi],bh 706 jmp short Lexit 707 708L12: 709 add esi,_modex_line_incr2 710 out dx,ax 711 mov [edi],bh 712 add edi,_modex_line_vertincr 713 loop L10 714 jmp short Lexit 715 716; bit mask shifted out 717 718L14: out dx,ax 719 mov [edi],bh 720 inc edi 721 or esi,esi 722 jns L15 723 add esi,_modex_line_incr1 724 loop L10 725 jmp short Lexit 726 727L15: 728 add esi,_modex_line_incr2 729 add edi,_modex_line_vertincr 730 loop L10 731 jmp short Lexit 732 733; routine for dy > dx (slope > 1) 734 735HiSlopeLine: 736 mov ebx,_modex_line_vertincr 737 mov al,MAP_MASK 738L21: out dx,ax 739 push eax 740 mov al,_modex_line_Color 741 mov [edi],al 742 pop eax 743 add edi,ebx 744 745L22: 746 or esi,esi 747 jns L23 748 749 add esi,_modex_line_incr1 750 loop L21 751 jmp short Lexit 752 753L23: 754 add esi,_modex_line_incr2 755 rol ah,1 756 adc edi,0 757lx21: loop L21 758 759; return to caller 760 761Lexit: 762 popa 763 ret 764 765 766 767_TEXT ENDS 768 769 770 END 771