1 ; 2 ; swgrph - SW screen graphics 3 ; 4 ; Copyright (C) 1984-2003 David L. Clark. 5 ; This program is free software; you can redistribute it and/or modify it under 6 ; the terms of the GNU General Public License as published by the Free Software 7 ; Foundation; either version 2 of the License, or (at your option) any later 8 ; version. This program is distributed in the hope that it will be useful, 9 ; but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 10 ; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 ; more details. You should have received a copy of the GNU General Public 12 ; License along with this program; if not, write to the Free Software Foundation, 13 ; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 14 ; 15 ; Modification History: 16 ; 84-02-21 Development 17 ; 84-06-13 PCjr Speed-up 18 ; 85-11-05 Atari 19 ; 87-03-10 Microsoft compiler 20 ; 87-03-13 Splatted ox display 21 ; 94-12-18 C6 Compiler 22 ; 2003-01-27 GNU General Public License 23 ; 24 ; 25 26 27 % .MODEL model,lang 28 INCLUDE mixed.inc 29 30 .CODE 31 32 include segments.h 33 include sw.ha 34 35 public swdisp 36 public swground 37 public swputsym 38 public swputcol 39 public swclrcol 40 public swpntsym 41 public swpntcol 42 public get_type 43 public set_type 44 public setvdisp 45 public setadisp 46 47 extrn dispoxsplat:near 48 49 50 51 ;---------------------------------------------------------------------------- 52 53 54 swdisp: 55 push BP ; save registers 56 push DI 57 push SI 58 push ES 59 60 ; 61 ; setup display in video ram 62 ; 63 call setvdisp 64 65 ; 66 ; for each object, delete the object from the screen if it currently 67 ; displayed, and re-draw the object if still on the screen 68 ; 69 70 mov BX,objtop ; address of first object 71 72 disploop: 73 or BX,BX ; last object? 74 jnz disp00 ; NO - continue 75 jmp dispdel ; YES - leave 76 77 disp00: mov AX,OB_DELFLG[BX] ; is the object being deleted and 78 and AX,OB_DRWFLG[BX] ; redrawn? 79 jz disp0 ; NO - continue 80 cmp word ptr OB_SYMHGT[BX],1; is the object trivial? 81 je disp0 ; YES- continue 82 mov AX,OB_OLDSYM[BX] ; are the old object display and the 83 cmp AX,OB_NEWSYM[BX] ; new object display the same 84 jne disp0 ; NO - continue 85 mov AX,OB_Y[BX] ; is the object moving 86 cmp AX,OB_OLDY[BX] ; vertically? 87 jne disp0 ; YES - continue 88 mov AX,OB_OLDX[BX] ; is the object moving 89 add AX,displx ; with the player in 90 cmp AX,OB_X[BX] ; the x direction? 91 jnz disp0 ; NO - continue 92 jmp disp11 ; test display function 93 94 disp0: 95 cmp word ptr OB_DELFLG[BX],0; is this object to be deleted? 96 jz disp1 ; NO - skip 97 mov DI,OB_OLDY[BX] ; YES - save old object y coord 98 mov SI,OB_OLDX[BX] ; old object x coord 99 mov BP,OB_OLDSYM[BX] ; old symbol 100 mov AX,OB_CLR[BX] ; color of object 101 call drawsym ; remove by xor draw 102 103 disp1: cmp word ptr OB_DRWFLG[BX],0; is the object to be drawn 104 jz disp3 ; NO - skip 105 mov SI,OB_X[BX] ; YES - load object x coord 106 cmp SI,displx ; object past left margin? 107 jl disp2 ; YES - skip 108 cmp SI,disprx ; object past right margin? 109 jg disp2 ; YES - skip 110 sub SI,displx ; get object x coord 111 call testox ; hidden due to splatted ox? 112 je disp2 ; YES - skip 113 114 mov OB_OLDX[BX],SI ; save object x coord 115 mov DI,OB_Y[BX] ; save object y coord 116 mov OB_OLDY[BX],DI 117 mov BP,OB_NEWSYM[BX] ; new symbol 118 mov AX,OB_CLR[BX] ; color of object 119 call drawsym ; draw the object 120 121 disp11: cmp word ptr OB_DRAWF[BX],0 ; is there a display function? 122 jz disp3 ; NO - skip 123 push BX ; YES- save object pointer 124 call word ptr OB_DRAWF[BX] ; call function 125 pop BX ; restore BX 126 jmp disp3 127 128 disp2: mov word ptr OB_DRWFLG[BX],0; indicate object not drawn 129 disp3: mov BX,OB_NEXT[BX] ; get next object in list 130 jmp disploop ; loop back 131 132 ; 133 ; for each object in the newly deleted object list, delete 134 ; any images on screen 135 ; 136 137 dispdel: 138 139 mov BX,deltop ; start of deleted object list 140 141 dispdlop: 142 or BX,BX ; last object on list? 143 jz dispret ; YES - leave 144 145 cmp word ptr OB_DELFLG[BX],0; is this object to be deleted? 146 jz dispd1 ; NO - skip 147 mov DI,OB_OLDY[BX] ; YES - save old object y coord 148 mov SI,OB_OLDX[BX] ; old object x coord 149 mov BP,OB_OLDSYM[BX] ; old symbol 150 mov AX,OB_CLR[BX] ; color of object 151 call drawsym ; remove by xor draw 152 153 dispd1: mov BX,OB_NEXT[BX] ; get next object in list 154 jmp dispdlop ; loop back 155 156 dispret: 157 cmp word ptr oxsplatted,1 ; ox splatted on screen? 158 je dispdone ; YES - leave 159 call dispgrnd ; update ground display 160 cmp word ptr splatox,0 ; hit the ox? 161 jz dispdone ; NO - skip 162 call dispoxsplat ; YES- splat the ox 163 164 dispdone: 165 mov word ptr dispinit,0 ; reset initialized display flag 166 mov word ptr forcdisp,0 ; reset force display flag 167 pop ES ; restore registers 168 pop SI 169 pop DI 170 pop BP 171 ret 172 173 174 ;----------------------------------------------------------------------------- 175 176 testox: 177 cmp word ptr oxsplatted,1 ; OX splatted? 178 jne testr ; NO - leave 179 180 push AX ; save registers 181 push DX ; 182 mov AX,SI ; X coordinate in AX 183 mov DL,106 ; divide by 320/3 184 div DL ; 185 test AL,1 ; test if to display 186 pop DX ; restore registers 187 pop AX ; 188 189 testr: ret ; return 190 191 ;----------------------------------------------------------------------------- 192 193 dispgrnd: 194 cld ; clear direction flag 195 cmp word ptr dispinit,1 ; first display after initialization? 196 je dg1 ; YES - skip erase of old ground 197 cmp dispdx,0 ; is screen moving? 198 jnz dg0 ; YES - continue 199 cmp forcdisp,0 ; NO - is display to be forced 200 jnz dg0 ; YES - continue 201 ret ; NO - return 202 203 dg0: lea SI,grndsave ; NO - erase old ground by xor 204 call dispg ; redraw of ground 205 206 dg1: mov AX,DS ; set ES to DS for ground save 207 mov ES,AX 208 lea SI,ground ; start of ground address 209 add SI,displx ; start address of displayed ground 210 mov BX,SI ; save it 211 lea DI,grndsave ; address of ground save area 212 mov CX,(SCR_WDTH/2) ; screen width in words 213 rep movsw ; save ground being displayed 214 215 mov SI,BX ; start address of displayed ground 216 call dispg ; display it 217 ret 218 219 dispg: mov DX,disproff ; down raster line offset in DX 220 mov BX,DX 221 sub BX,SCR_LINW ; up raster line offset in BX 222 223 mov AL,[SI] ; initial ground height in AL 224 mov CL,AL ; in CL 225 sub AL,(SCR_HGHT-1) ; inverted ground height 226 neg AL ; 227 shr AL,1 ; adjust for even/odd scan lines 228 mov CH,SCR_LINW ; line width 229 mul CH ; byte offset of first dot in AX 230 231 test CL,1 ; is first dot on an odd scanline 232 jnz dg2 ; NO - skip 233 add AX,DX ; YES- move to next segment 234 neg BX ; reverse up/down offsets 235 neg DX 236 xchg BX,DX 237 238 dg2: add AX,dispoff ; add display offset 239 mov DI,AX ; set final register 240 241 mov BP,SI ; start of ground to display 242 add BP,SCR_WDTH ; end of ground to display 243 mov CH,0C0H ; initial ground dot mask 244 mov AH,[SI] ; initial 'last ground height' 245 mov ES,dispseg ; screen segment 246 247 dgloop: 248 lodsb ; get next ground height 249 cmp AL,AH ; compare new height to old 250 ja dga ; ABOVE 251 jb dgb ; BELOW 252 253 xor ES:[DI],CH ; EQUAL - plot dot 254 jmp dgn ; get next pixel 255 256 dga: add DI,BX ; ABOVE - move up a scan line 257 neg BX ; reverse up/down offsets 258 neg DX 259 xchg BX,DX 260 xor ES:[DI],CH ; plot dot 261 inc AH ; move up a height 262 cmp AL,AH ; where we want to be? 263 jne dga ; NO - up again 264 jmp dgn ; YES- get next pixel 265 266 dgb: add DI,DX ; BELOW - move down a scan line 267 neg BX ; reverse up/down offsets 268 neg DX 269 xchg BX,DX 270 xor ES:[DI],CH ; plot dot 271 dec AH ; move down a height 272 cmp AL,AH ; where we want to be? 273 jne dgb ; NO - up again 274 275 dgn: shr CH,1 ; shift plot mask right 2 bits 276 shr CH,1 ; 277 or CH,CH ; end of byte? 278 jnz dgloop ; NO - get next ground height 279 inc DI ; YES- increment a byte 280 mov CH,0C0H ; reset plot mask 281 cmp SI,BP ; end of ground display? 282 jb dgloop ; NO - get next ground height 283 ret ; YES- bye 284 285 286 287 ;----------------------------------------------------------------------------- 288 289 swground: 290 push BP ; save registers 291 push DI 292 push SI 293 push ES 294 call dispgrnd ; display ground for title screen 295 pop ES ; restore registers 296 pop SI 297 pop DI 298 pop BP 299 ret 300 301 302 303 304 ;----------------------------------------------------------------------------- 305 306 swclrcol: 307 push DI ; save registers 308 push SI 309 push ES 310 311 cld ; clear direction flag 312 mov ES,dispseg ; get current display segment 313 mov SI,dispoff ; get current display offset 314 add SI,(((SCR_HGHT/2)-1)*SCR_LINW) ; offset of last line 315 call clearhalf ; clear even lines 316 add SI,disproff 317 call clearhalf ; clear odd lines 318 319 pop ES ; restore registers 320 pop SI 321 pop DI 322 ret 323 324 325 clearhalf proc near 326 mov DI,SI ; starting address 327 mov CX,8 ; clear 8 lines 328 xor AX,AX ; zero pattern in AX 329 330 cloop: stosw ; clear 48 pixels 331 stosw 332 stosw 333 stosw 334 stosw 335 stosw 336 sub DI,(SCR_LINW+12) ; reset to previous line 337 loop cloop ; do 8 times 338 ret 339 clearhalf endp 340 341 342 ;----------------------------------------------------------------------------- 343 344 swputsym: 345 mov BX,SP ; new frame pointer 346 push BP ; save other registers 347 push SI 348 push DI 349 push ES 350 351 mov SI,2[BX] ; load symbol x ccord 352 mov DI,4[BX] ; symbol y coord 353 mov BX,6[BX] ; object address 354 mov BP,OB_NEWSYM[BX] ; current symbol 355 mov AX,OB_CLR[BX] ; color of object 356 call drawsym ; draw symbol 357 358 pop ES ; restore registers 359 pop DI 360 pop SI 361 pop BP 362 ret 363 364 365 ;----------------------------------------------------------------------------- 366 367 swpntsym: 368 push BP ; save SI 369 mov BP,SP ; new frame pointer 370 push SI ; save other registers 371 push DI 372 push ES 373 374 mov SI,4[BP] ; load point x ccord 375 mov DI,6[BP] ; point y coord 376 mov BP,8[BP] ; point color 377 call drawpnt ; display point 378 379 pop ES ; restore registers 380 pop DI 381 pop SI 382 pop BP 383 ret 384 385 386 ;----------------------------------------------------------------------------- 387 388 swputcol: 389 mov BX,SP ; new frame pointer 390 push BP ; save other registers 391 push SI 392 push DI 393 push ES 394 395 mov SI,2[BX] ; load symbol x ccord 396 mov DI,4[BX] ; symbol y coord 397 mov BX,6[BX] ; object address 398 mov BP,OB_NEWSYM[BX] ; current symbol 399 400 call setup ; setup display parameters 401 jnz putc0 ; symbol is a point? 402 call drawpntc ; YES - draw point 403 jmp putcret ; return 404 405 ; plot a rastor line of a symbol to the video ram. Register 406 ; values at this time are 407 ; AL - byte count of segment display 408 ; AH - byte count of horizontal wraparound 409 ; BX - offset from end of symbol line to beginning of next 410 ; CL - number of bits to shift each byte 411 ; BP - number of lines to display 412 ; SI - pointer to first symbol byte to display 413 ; DI - pointer to first video ram byte to use 414 415 putc0: 416 mov retcode,0 ; zero return code 417 putc1: 418 push AX ; save segment lengths AL 419 push DI ; save current video ram location 420 xor CH,CH ; reset byte rotation hold areas 421 push BX ; save line to line adjustment 422 lea BX,CS:trans ; address of byte translation table 423 call dispputc ; display segment 424 425 cmp AH,0 ; wrap around segment ? 426 jl putc2 ; NO- goto normal carry processing 427 mov AL,AH ; YES- add wrap segment length 428 xor AH,AH ; to symbol address SI 429 add SI,AX 430 jmp putc3 ; jump carry 431 432 putc2: 433 cmp CH,0 ; shift carry present 434 jz putc3 ; NO -goto loop increment 435 mov DH,CH ; byte to plot 436 call collide ; collision detection 437 xor ES:[DI],CH ; plot carry to ram 438 putc3: 439 pop BX ; restore line to line adjustment 440 pop DI ; restore old start location 441 add DI,BX ; destination to start of new line 442 xchg BX,adjrast ; exchange line to line offsets 443 pop AX ; restore segment lengths 444 dec BP ; decrement line counter 445 jnz putc1 ; loop until line counter is 0 446 447 mov AL,retcode ; return code 448 xor AH,AH 449 450 putcret: 451 pop ES ; restore registers 452 pop DI 453 pop SI 454 pop BP 455 ret 456 457 ; plot a rastor line segment to the video ram. Register 458 ; values at this time are 459 ; AL - byte count of segment 460 ; AH - ---don't care--- 461 ; BX - translate table address 462 ; CL - number of bits to shift each byte 463 ; CH - carry from previous shift 464 ; DX - screen line length in bytes 465 ; SI - pointer to first symbol byte to display 466 ; DI - pointer to first video ram byte to use 467 468 dispputc: 469 xor DL,DL ; clear shift carry area 470 mov DH,[SI] ; symbol character 471 shr DX,CL ; shift right CL bits 472 or DH,CH ; or carry from previous shift 473 call collide ; collision detection 474 xor ES:[DI],DH ; plot to video ram 475 mov CH,DL ; save carry 476 inc SI ; increment symbol pointer 477 inc DI ; video ram pointer 478 dec AL ; decrement byte counter 479 jnz dispputc ; loop until segment done 480 481 ret 482 483 484 485 ;----------------------------------------------------------------------------- 486 487 swpntcol: 488 push BP ; save BP 489 mov BP,SP ; new frame pointer 490 push SI ; save other registers 491 push DI 492 push ES 493 494 mov SI,4[BP] ; load point x ccord 495 mov DI,6[BP] ; point y coord 496 mov BP,8[BP] ; point color 497 call drawpntc ; display point 498 499 pop ES ; restore registers 500 pop DI 501 pop SI 502 pop BP 503 ret 504 505 506 ;----------------------------------------------------------------------------- 507 508 drawsym: 509 push BX ; save object pointer 510 511 push BX ; set up mask for xor color adj. 512 mov BX,AX ; 513 and BX,3 ; 514 mov AL,CS:cmsktab[BX] ; 515 mov colmask,AL ; 516 pop BX ; 517 518 call setup ; setup display parameters 519 jnz ds1 ; symbol is a point? 520 call drawpnt ; YES - draw point 521 jmp dsret ; return 522 523 ; plot a rastor line of a symbol to the video ram. Register 524 ; values at this time are 525 ; AL - byte count of segment display 526 ; AH - byte count of horizontal wraparound 527 ; BX - offset from end of symbol line to beginning of next 528 ; CL - number of bits to shift each byte 529 ; BP - number of lines to display 530 ; SI - pointer to first symbol byte to display 531 ; DI - pointer to first video ram byte to use 532 533 ds1: 534 push AX ; save segment lengths AL 535 push DI ; save current video ram location 536 xor CH,CH ; reset byte rotation hold areas 537 push BX ; save line to line adjustment 538 lea BX,CS:trans ; address of byte translation table 539 call dispds ; display segment 540 541 cmp AH,0 ; wrap around segment ? 542 jl ds2 ; NO- goto normal carry processing 543 mov AL,AH ; YES- add wrap segment length 544 xor AH,AH ; to symbol address SI 545 add SI,AX 546 jmp ds3 ; jump carry 547 548 ds2: 549 cmp CH,0 ; shift carry present 550 jz ds3 ; NO -goto loop increment 551 mov DH,CH ; plot carry into ram using 552 call adjcolor ; color adjustment 553 xor ES:[DI],DH ; 554 ds3: 555 pop BX ; restore line to line adjustment 556 pop DI ; restore old start location 557 add DI,BX ; destination to start of new line 558 xchg BX,adjrast ; exchange line to line offsets 559 pop AX ; restore segment lengths 560 dec BP ; decrement line counter 561 jnz ds1 ; loop until line counter is 0 562 563 dsret: 564 pop BX ; restore registers 565 ret 566 567 568 569 ; plot a rastor line segment to the video ram. Register 570 ; values at this time are 571 ; AL - byte count of segment 572 ; AH - ---don't care--- 573 ; BX - rastor line offset 574 ; CL - number of bits to shift each byte 575 ; CH - carry from previous shift 576 ; DX - screen line length in bytes 577 ; SI - pointer to first symbol byte to display 578 ; DI - pointer to first video ram byte to use 579 580 dispds: 581 xor DL,DL ; clear shift carry area 582 mov DH,[SI] ; symbol character 583 shr DX,CL ; shift right CL bits 584 or DH,CH ; or carry from previous shift 585 586 call adjcolor ; adjust symbol for color of object 587 588 xor ES:[DI],DH ; plot to video ram 589 mov CH,DL ; save carry 590 inc SI ; increment symbol pointer 591 inc DI ; video ram pointer 592 dec AL ; decrement byte counter 593 jnz dispds ; loop until segment done 594 595 ret 596 597 598 599 ;----------------------------------------------------------------------------- 600 601 drawpnt: 602 603 ; invert row requested 604 605 sub DI,(SCR_HGHT - 1 ) 606 neg DI 607 608 ; calculate the number of bits to rotate the colour 609 ; the column position is not byte aligned. (CL) 610 611 mov CX,SI ; pixel column requested 612 and CL,03H ; pixel offset in CL 613 sub CL,3 ; inverted 614 neg CL 615 shl CL,1 ; bits to rotate in CL 616 617 ; determine first video ram byte to use and store in AX 618 619 mov AX,DI ; starting row in AX. 620 shr AX,1 ; divide by 2 for even/odd rastor lines 621 mov DX,SCR_WDTH 622 mul DX ; end of previous row in DX:AX 623 add AX,SI ; pixel offset in DX:AX 624 adc DX,0 ; handle carry into DX 625 shr DX,1 ; shift DX:AX by 2 626 rcr AX,1 627 shr DX,1 628 rcr AX,1 ; byte offset in AX 629 mov SI,AX ; in SI 630 631 ; adjust byte offset if line odd 632 633 test DI,01H ; Row odd? 634 jz dp1 ; NO - skip 635 add SI,disproff ; first video ram byte 636 dp1: 637 mov AX,dispseg ; save video ram segment 638 mov ES,AX 639 add SI,dispoff 640 641 ; plot the current colour, or exclusive or the current colour based 642 ; on the first bit of the colour. 643 644 mov AX,BP 645 and AL,83H 646 test AL,80H 647 jnz dp2 648 649 mov CH,03H 650 shl CH,CL 651 mov DH,ES:[SI] 652 and CH,DH 653 xor DH,CH 654 rol AL,CL 655 or DH,AL 656 mov ES:[SI],DH 657 ret 658 659 dp2: and AL,7FH 660 shl AL,CL 661 xor ES:[SI],AL 662 ret 663 664 665 666 ;----------------------------------------------------------------------------- 667 668 drawpntc: 669 670 ; invert row requested 671 672 sub DI,(SCR_HGHT - 1 ) 673 neg DI 674 675 ; calculate the number of bits to rotate the colour 676 ; the column position is not byte aligned. (CL) 677 678 mov CX,SI ; pixel column requested 679 and CL,03H ; pixel offset in CL 680 sub CL,3 ; inverted 681 neg CL 682 shl CL,1 ; bits to rotate in CL 683 684 ; determine first video ram byte to use and store in AX 685 686 mov AX,DI ; starting row in AX. 687 shr AX,1 ; divide by 2 for even/odd rastor lines 688 mov DX,SCR_WDTH 689 mul DX ; end of previous row in DX:AX 690 add AX,SI ; pixel offset in DX:AX 691 adc DX,0 ; handle carry into DX 692 shr DX,1 ; shift DX:AX by 2 693 rcr AX,1 694 shr DX,1 695 rcr AX,1 ; byte offset in AX 696 mov SI,AX ; in BX 697 698 ; adjust byte offset if line odd 699 700 test DI,01H ; Row odd? 701 jz dpc1 ; NO - skip 702 add SI,disproff ; first video ram byte 703 dpc1: 704 mov AX,dispseg ; save video ram segment 705 mov ES,AX 706 add SI,dispoff 707 708 ; create mask to return colour of point previous to plot 709 710 mov CH,03H 711 shl CH,CL 712 and CH,ES:[SI] 713 714 ; plot the current colour, or exclusive or the current colour based 715 ; on the first bit of the colour. 716 717 mov AX,BP 718 and AL,83H 719 test AL,80H 720 jnz dpc2 721 722 xor ES:[SI],CH 723 rol AL,CL 724 or ES:[SI],AL 725 jmp dpc3 726 727 dpc2: and AL,7FH 728 shl AL,CL 729 xor ES:[SI],AL 730 731 ; 732 ; return the color code found 733 ; 734 735 dpc3: 736 shr CH,CL 737 mov AL,CH 738 xor AH,AH 739 ret 740 741 742 ;---------------------------------------------------------------------------- 743 744 ; 745 ; if symbol height and width are 1, signal point code 746 ; 747 748 setup: 749 cmp word ptr OB_SYMHGT[BX],1 750 jne stp1 751 cmp word ptr OB_SYMWDT[BX],1 752 jne stp1 753 ret 754 755 ; invert row requested 756 757 stp1: 758 sub DI,(SCR_HGHT - 1 ) 759 neg DI 760 761 ; calculate the number of bits to rotate a symbol byte if 762 ; the column position is not byte aligned. (CL) 763 764 mov CX,SI ; pixel column requested 765 and CL,03H ; bit offset in CL 766 shl CL,1 ; bits to rotate in CL 767 768 ; calculate byte count for on scan line taking into account vertical 769 ; screen boundaries. Place in AL. Place any overwrap in AH. 770 771 mov AX,OB_SYMWDT[BX] ; symbol width in pixels 772 shr AX,1 ; then in bytes in AL 773 shr AX,1 774 775 mov DX,SI ; pixel column requested 776 shr DX,1 ; pixel byte offset in DL 777 shr DX,1 778 sub DL,SCR_LINW ; screen width in bytes 779 neg DL ; available bytes for symbol in DL 780 781 mov AH,AL 782 sub AH,DL ; symbol width less than available? 783 jle stp2 ; YES - skip 784 mov AL,DL ; NO - available bytes in AL 785 stp2: 786 787 ; calculate line count for the symbol taking into account horizontal 788 ; boundaries, and push in stack 789 790 push AX ; save AX, segment length count 791 mov AX,OB_SYMHGT[BX] ; symbol height in AX 792 mov DX,SCR_HGHT ; screen height 793 sub DX,DI ; available lines for symbol in DX 794 cmp AX,DX ; symbol height less than available? 795 jbe stp3 ; YES - skip 796 mov AX,DX ; NO - available lines in DI 797 stp3: 798 push AX 799 800 ; determine first video ram byte to use and store in AX 801 802 mov AX,DI ; starting row in AX. 803 shr AX,1 ; divide by 2 for even/odd rastor lines 804 mov DX,SCR_WDTH 805 mul DX ; end of previous row in DX:AX 806 add AX,SI ; pixel offset in DX:AX 807 adc DX,0 ; handle carry into DX 808 shr DX,1 ; shift DX:AX by 2 809 rcr AX,1 810 shr DX,1 811 rcr AX,1 ; byte offset in AX 812 813 ; store rastor line width in DX, and calculate line to line offsets 814 ; as 'rastor line offset' and DX - 'rastor line offset' 815 816 mov DX,SCR_LINW ; line width in bytes in DX 817 mov BX,disproff ; even to odd line offset in BX 818 mov adjrast,DX 819 sub adjrast,BX ; odd to even line offset 820 821 ; adjust first video ram byte to use, and reverse rastor line 822 ; offsets if starting on an odd line 823 824 test DI,01H ; Row odd? 825 jz stp4 ; NO - skip 826 add AX,BX ; first video ram byte 827 xchg BX,adjrast ; exchange offsets 828 stp4: 829 830 ; setup final registers for display 831 832 mov SI,dispseg ; save video ram segment 833 mov ES,SI 834 mov SI,BP ; access pointer to symbol 835 mov DI,AX ; set video ram destination 836 add DI,dispoff 837 pop BP ; line count for display 838 pop AX ; restore segment length 839 840 or AX,AX ; return not zero 841 ret 842 843 844 ;----------------------------------------------------------------------------- 845 ; 846 ; routine to perform collision detection between DH and ES:[DI] 847 ; 848 849 collide: 850 push AX ; save AX 851 mov AL,DH ; byte to plot in AL 852 xlat CS:trans ; translate 853 and AL,ES:[DI] ; non-zero if collision 854 or retcode,AL 855 pop AX 856 ret 857 858 859 ;------------------------------------------------------------------------------ 860 ; 861 ; routine to adjust the color of an object 862 ; 863 864 adjcolor: 865 push AX ; save AX 866 mov AL,DH ; byte to plot in AL 867 xlat CS:trans ; translate to ones for xor 868 and AL,colmask ; mask off if color 1 869 xor DH,AL ; convert 01-10 if color 2 870 pop AX ; restore AX 871 ret 872 873 ; 874 ; translation table corresponding to any 2-bit non zero portion 875 ; of a byte set to 11. 876 ; 877 trans db 00H,03H,03H,03H,0CH,0FH,0FH,0FH,0CH,0FH,0FH,0FH,0CH,0FH,0FH,0FH 878 db 30H,33H,33H,33H,3CH,3FH,3FH,3FH,3CH,3FH,3FH,3FH,3CH,3FH,3FH,3FH 879 db 30H,33H,33H,33H,3CH,3FH,3FH,3FH,3CH,3FH,3FH,3FH,3CH,3FH,3FH,3FH 880 db 30H,33H,33H,33H,3CH,3FH,3FH,3FH,3CH,3FH,3FH,3FH,3CH,3FH,3FH,3FH 881 db 0C0H,0C3H,0C3H,0C3H,0CCH,0CFH,0CFH,0CFH,0CCH,0CFH,0CFH,0CFH,0CCH,0CFH,0CFH,0CFH 882 db 0F0H,0F3H,0F3H,0F3H,0FCH,0FFH,0FFH,0FFH,0FCH,0FFH,0FFH,0FFH,0FCH,0FFH,0FFH,0FFH 883 db 0F0H,0F3H,0F3H,0F3H,0FCH,0FFH,0FFH,0FFH,0FCH,0FFH,0FFH,0FFH,0FCH,0FFH,0FFH,0FFH 884 db 0F0H,0F3H,0F3H,0F3H,0FCH,0FFH,0FFH,0FFH,0FCH,0FFH,0FFH,0FFH,0FCH,0FFH,0FFH,0FFH 885 db 0C0H,0C3H,0C3H,0C3H,0CCH,0CFH,0CFH,0CFH,0CCH,0CFH,0CFH,0CFH,0CCH,0CFH,0CFH,0CFH 886 db 0F0H,0F3H,0F3H,0F3H,0FCH,0FFH,0FFH,0FFH,0FCH,0FFH,0FFH,0FFH,0FCH,0FFH,0FFH,0FFH 887 db 0F0H,0F3H,0F3H,0F3H,0FCH,0FFH,0FFH,0FFH,0FCH,0FFH,0FFH,0FFH,0FCH,0FFH,0FFH,0FFH 888 db 0F0H,0F3H,0F3H,0F3H,0FCH,0FFH,0FFH,0FFH,0FCH,0FFH,0FFH,0FFH,0FCH,0FFH,0FFH,0FFH 889 db 0C0H,0C3H,0C3H,0C3H,0CCH,0CFH,0CFH,0CFH,0CCH,0CFH,0CFH,0CFH,0CCH,0CFH,0CFH,0CFH 890 db 0F0H,0F3H,0F3H,0F3H,0FCH,0FFH,0FFH,0FFH,0FCH,0FFH,0FFH,0FFH,0FCH,0FFH,0FFH,0FFH 891 db 0F0H,0F3H,0F3H,0F3H,0FCH,0FFH,0FFH,0FFH,0FCH,0FFH,0FFH,0FFH,0FCH,0FFH,0FFH,0FFH 892 db 0F0H,0F3H,0F3H,0F3H,0FCH,0FFH,0FFH,0FFH,0FCH,0FFH,0FFH,0FFH,0FCH,0FFH,0FFH,0FFH 893 894 ; 895 ; mask for xor color adjustments 896 ; 897 898 cmsktab db 0,0,0FFH,0 899 900 901 902 ;------------------------------------------------------------------------------ 903 ; 904 ; get_type(); 905 ; set_type( type ); 906 ; 907 ; get/set screen types 908 ; 909 910 911 get_type: 912 mov AH,15 ; get state function 913 int 10H ; get video state in AL 914 xor AH,AH ; in AX 915 ret ; return 916 917 918 set_type: 919 push BP ; save frame pointer 920 mov BP,SP ; new frame pointer 921 mov AL,@AB[BP] ; get mode in AL 922 xor AH,AH ; set video mode function 923 int 10H ; do it 924 pop BP ; restore frame pointer 925 ret ; return 926 927 928 929 ;------------------------------------------------------------------------------ 930 ; 931 ; setvdisp(); 932 ; setadisp(); 933 ; 934 ; set current display to video/alternate buffer 935 ; 936 937 938 setvdisp: 939 mov word ptr dispseg,SCR_SEGM 940 mov word ptr dispoff,0 941 mov word ptr disproff,SCR_ROFF 942 ret 943 944 945 setadisp: 946 mov word ptr dispseg,DS 947 mov word ptr dispoff,( offset DGROUP:auxdisp - 1000H ) 948 mov word ptr disproff,1000H 949 ret ; return 950 951 952 953 954 .DATA 955 956 adjrast dw ? ; rastor line offset save area 957 colmask db ? ; 958 retcode db ? ; return code 959 grndsave db SCR_WDTH dup (?) ; ground save area 960 dispseg dw ? ; Display segment 961 dispoff dw ? ; offset 962 disproff dw ? ; inter bank offset 963 964 extrn displx:word ; Display left and right bounds 965 extrn disprx:word 966 extrn dispdx:word ; Display shift 967 extrn auxdisp:byte ; auxiliary display buffer 968 extrn ground:byte ; Ground height by pixel 969 extrn dispinit:word ; Initialized display flag 970 extrn forcdisp:word ; Force display flag 971 extrn objtop:word ; First object in object list 972 extrn deltop:word ; First object in deleted object list 973 extrn splatox:word ; display splatted ox 974 extrn oxsplatted:word ; an ox has bben splatted 975 976 end 977 ÿ