drawing.s (37338B)
1;; Optimised Drawing library 2;; By Jon Fuge (jonny@q-continuum.demon.co.uk) based on original file 3;; Updates 4;; 990223 Michael Removed mod_col, splitting it up into 5;; fg_colour, bg_colour, and draw_mode 6;; Note: some optimisations are available with unneded PUSH DE/POP DE's 7 8 .include "global.s" 9 10 .globl .init_vram 11 .globl .copy_vram 12 13 .globl .drawing_lcd, .drawing_vbl 14 .globl .bg_colour, .fg_colour, .draw_mode 15 16 .M_SOLID = 0x00 17 .M_OR = 0x01 18 .M_XOR = 0x02 19 .M_AND = 0x03 20 21 ;; Format of mod_col 22 ;; 7 6 5 4 3 2 1 0 23 ;; mode fg bg 24 25 .area _DRAW_HEADER (ABS) 26 27 .org 0x70 28.drawing_bits_tbl:: 29 .byte 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 30 .byte 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 31 32 .org .MODE_TABLE+4*.G_MODE 33 JP .gmode 34 35 .module Drawing1 36 37 .area _DATA 38 39 ;; Fill style 40.style: 41 .ds 0x01 42 ;; Various varibles 43.x_s: 44 .ds 2 45.y_s: 46 .ds 2 47.delta_x: 48 .ds 1 49.delta_y: 50 .ds 1 51.l_inc: 52 .ds 1 53.l_d: 54 .ds 2 55.dinc1: 56 .ds 2 57.dinc2: 58 .ds 2 59.tx: 60 .ds 1 61.ty: 62 .ds 1 63 64 .area _HOME 65 66 ;; Enter graphic mode 67.gmode:: 68 DI ; Disable interrupts 69 70 ;; Turn the screen off 71 LDH A,(.LCDC) 72 AND #LCDCF_ON 73 JR Z,1$ 74 75 ;; Turn the screen off 76 CALL .display_off 771$: 78 LD HL,#0x8000+0x10*0x10 79 LD DE,#0x1800-0x18*0x10 80 LD B,#0x00 81 CALL .init_vram ; Init the charset at 0x8000 82 83 ;; Install interrupt routines 84 LD BC,#.drawing_vbl 85 CALL .add_VBL 86 LD BC,#.drawing_lcd 87 CALL .add_LCD 88 89 LD A,#72 ; Set line at which LCD interrupt occurs 90 LDH (.LYC),A 91 92 LD A,#STATF_LYC 93 LDH (.STAT),A 94 95 LDH A,(.IE) 96 OR #.LCD_IFLAG ; Enable LCD interrupt 97 LDH (.IE),A 98 99 ;; (9*20) = 180 tiles are used in the upper part of the screen 100 ;; (9*20) = 180 tiles are used in the lower part of the screen 101 ;; => We have 24 tiles free 102 ;; We keep 16 at 0x8000->0x80FF, and 8 at 0x9780->97FF 103 104 LD HL,#0x9800 105 LD A,#0x10 ; Keep 16 tiles free 106 LD BC,#12 ; 12 unused columns 107 LD E,#18 ; 18 lines 1082$: 109 LD D,#20 ; 20 used columns 1103$: 111 LD (HL+),A 112 INC A 113 DEC D 114 JR NZ,3$ 115 ADD HL,BC 116 DEC E 117 JR NZ,2$ 118 119 ;; Turn the screen on 120 LDH A,(.LCDC) 121 OR #(LCDCF_ON | LCDCF_BG8000 | LCDCF_BGON) 122 AND #~LCDCF_BG9C00 ; BG Bank = 0x9800 123 LDH (.LCDC),A 124 125 LD A,#.G_MODE 126 LD (.mode),A 127 128 ;; Setup the default colours and draw modes 129 LD A,#.M_SOLID 130 LD (.draw_mode),A 131 LD A,#0x03 ; Black 132 LD (.fg_colour),A 133 LD A,#0x00 ; White 134 LD (.bg_colour),A 135 136 EI ; Enable interrupts 137 138 RET 139 140 ;; Draw a full-screen image at (BC) 141.draw_image:: 142 LD HL,#0x8000+0x10*0x10 143 LD DE,#0x1680 144 CALL .copy_vram ; Move the charset 145 RET 146 147 ;; Replace tile data at (B,C) with data at DE and store old value at HL 148.switch_data:: 149 PUSH DE ; Save src 150 PUSH HL ; Save dst 151 LD L,B 152 SLA L 153 SLA L 154 SLA L 155 LD H,#0x00 156 ADD HL,HL 157 LD D,H 158 LD E,L 159 160 LD HL,#.y_table 161 SLA C 162 SLA C 163 SLA C 164 LD B,#0x00 165 ADD HL,BC 166 ADD HL,BC 167 LD A,(HL+) 168 LD H,(HL) 169 LD L,A 170 ADD HL,DE 171 172 LD B,H ; BC = src 173 LD C,L 174 POP HL ; HL = dst 175 PUSH BC ; Save dst 176 LD A,H 177 OR L 178 JR Z,1$ 179 LD DE,#0x10 180 CALL .copy_vram 1811$: 182 POP HL ; HL = dst 183 POP BC ; BC = src 184 LD A,B 185 OR C 186 JR Z,2$ 187 LD DE,#0x10 188 CALL .copy_vram 1892$: 190 RET 191 192 ;; Advance the cursor 193.adv_gcurs:: 194 PUSH HL 195 LD HL,#.tx ; X coordinate 196 LD A,#.MAXCURSPOSX 197 CP (HL) 198 JR Z,1$ 199 INC (HL) 200 JR 99$ 2011$: 202 LD (HL),#0x00 203 LD HL,#.ty ; Y coordinate 204 LD A,#.MAXCURSPOSY 205 CP (HL) 206 JR Z,2$ 207 INC (HL) 208 JR 99$ 2092$: 210 LD (HL),#0x00 21199$: 212 POP HL 213 RET 214 215 ;; Draw a circle from (B,C) with radius D 216.circle:: 217 LD A,B ;Store center values 218 LD (.x_s),A 219 LD A,C 220 LD (.y_s),A 221 222 XOR A 223 LD (.x_s+1),A 224 LD A,D 225 LD (.y_s+1),A 226 CPL 227 LD L,A 228 LD H,#0xFF 229 INC HL 230 LD BC,#0 231 ADD HL,BC 232 LD A,L 233 LD (.l_d+1),A 234 LD A,H 235 LD (.l_d),A 236 237cloop$: 238 LD A,(.x_s+1) 239 LD B,A 240 LD A,(.y_s+1) 241 SUB B 242 RET C 243 244 LD A,(.style) 245 OR A 246 CALL Z,.circplot 247 248 LD A,(.l_d) 249 BIT 7,A 250 JR Z,ycirc$ 251 252 LD A,(.style) 253 OR A 254 CALL NZ,.horlin 255 LD A,(.x_s+1) 256 INC A 257 LD (.x_s+1),A 258 LD A,(.l_d) 259 LD B,A 260 LD A,(.l_d+1) 261 LD C,A 262 LD H,#0 263 LD A,(.x_s+1) 264 LD L,A 265 ADD HL,HL 266 ADD HL,HL 267 ADD HL,BC 268 LD BC,#6 269 ADD HL,BC 270 LD A,H 271 LD (.l_d),A 272 LD A,L 273 LD (.l_d+1),A 274 JR cloop$ 275ycirc$: 276 LD A,(.style) 277 OR A 278 CALL NZ,.verlin 279 LD A,(.x_s+1) 280 INC A 281 LD (.x_s+1),A 282 LD B,#0 283 LD A,(.x_s+1) 284 LD C,A 285 LD H,#0xFF 286 LD A,(.y_s+1) 287 CPL 288 LD L,A 289 INC HL 290 ADD HL,BC 291 LD A,(.l_d) 292 LD B,A 293 LD A,(.l_d+1) 294 LD C,A 295 ADD HL,HL 296 ADD HL,HL 297 ADD HL,BC 298 LD BC,#10 299 ADD HL,BC 300 LD A,H 301 LD (.l_d),A 302 LD A,L 303 LD (.l_d+1),A 304 LD A,(.y_s+1) 305 DEC A 306 LD (.y_s+1),A 307 JP cloop$ 308 309.horlin:: 310 LD A,(.x_s) 311 LD B,A 312 LD A,(.y_s) 313 LD C,A 314 LD A,(.x_s+1) 315 LD D,A 316 LD A,(.y_s+1) 317 LD E,A 318 PUSH BC 319 PUSH DE 320 LD A,B 321 SUB E 322 LD H,A 323 LD A,B 324 ADD E 325 LD B,A 326 LD A,C 327 ADD D 328 LD C,A 329 LD D,H 330 LD E,C 331 CALL .line 332 POP DE 333 POP BC 334 LD A,D 335 OR A 336 RET Z 337 PUSH BC 338 PUSH DE 339 LD A,B 340 SUB E 341 LD H,A 342 LD A,B 343 ADD E 344 LD B,A 345 LD A,C 346 SUB D 347 LD C,A 348 LD D,H 349 LD E,C 350 CALL .line 351 POP DE 352 POP BC 353 RET 354 355.verlin:: 356 LD A,(.x_s) 357 LD B,A 358 LD A,(.y_s) 359 LD C,A 360 LD A,(.x_s+1) 361 LD D,A 362 LD A,(.y_s+1) 363 LD E,A 364 PUSH BC 365 PUSH DE 366 LD A,B 367 SUB E 368 LD H,A 369 LD A,B 370 ADD E 371 LD B,A 372 LD A,C 373 ADD D 374 LD C,A 375 LD D,H 376 LD E,C 377 CALL .line 378 POP DE 379 POP BC 380 PUSH BC 381 PUSH DE 382 LD A,B 383 SUB E 384 LD H,A 385 LD A,B 386 ADD E 387 LD B,A 388 LD A,C 389 SUB D 390 LD C,A 391 LD D,H 392 LD E,C 393 CALL .line 394 POP DE 395 POP BC 396 LD A,D 397 SUB E 398 RET Z 399 PUSH BC 400 PUSH DE 401 LD A,B 402 SUB D 403 LD H,A 404 LD A,B 405 ADD D 406 LD B,A 407 LD A,C 408 SUB E 409 LD C,A 410 LD D,H 411 LD E,C 412 CALL .line 413 POP DE 414 POP BC 415 PUSH BC 416 PUSH DE 417 LD A,B 418 SUB D 419 LD H,A 420 LD A,B 421 ADD D 422 LD B,A 423 LD A,C 424 ADD E 425 LD C,A 426 LD D,H 427 LD E,C 428 CALL .line 429 POP DE 430 POP BC 431 RET 432 433.circplot:: 434 LD A,(.x_s) 435 LD B,A 436 LD A,(.y_s) 437 LD C,A 438 LD A,(.x_s+1) 439 LD D,A 440 LD A,(.y_s+1) 441 LD E,A 442 PUSH BC 443 PUSH DE 444 LD A,B 445 ADD D 446 LD B,A 447 LD A,C 448 SUB E 449 LD C,A 450 CALL .plot 451 POP DE 452 POP BC 453 PUSH BC 454 PUSH DE 455 LD A,B 456 SUB E 457 LD B,A 458 LD A,C 459 SUB D 460 LD C,A 461 CALL .plot 462 POP DE 463 POP BC 464 PUSH BC 465 PUSH DE 466 LD A,B 467 SUB D 468 LD B,A 469 LD A,C 470 ADD E 471 LD C,A 472 CALL .plot 473 POP DE 474 POP BC 475 PUSH BC 476 PUSH DE 477 LD A,B 478 ADD E 479 LD B,A 480 LD A,C 481 ADD D 482 LD C,A 483 CALL .plot 484 POP DE 485 POP BC 486 487 LD A,D 488 OR A 489 RET Z 490 SUB E 491 RET Z 492 493 PUSH BC 494 PUSH DE 495 LD A,B 496 SUB D 497 LD B,A 498 LD A,C 499 SUB E 500 LD C,A 501 CALL .plot 502 POP DE 503 POP BC 504 PUSH BC 505 PUSH DE 506 LD A,B 507 SUB E 508 LD B,A 509 LD A,C 510 ADD D 511 LD C,A 512 CALL .plot 513 POP DE 514 POP BC 515 PUSH BC 516 PUSH DE 517 LD A,B 518 ADD D 519 LD B,A 520 LD A,C 521 ADD E 522 LD C,A 523 CALL .plot 524 POP DE 525 POP BC 526 PUSH BC 527 PUSH DE 528 LD A,B 529 ADD E 530 LD B,A 531 LD A,C 532 SUB D 533 LD C,A 534 CALL .plot 535 POP DE 536 POP BC 537 RET 538 539 ;; Draw a box between (B,C) and (D,E) 540.box:: 541 LD A,(.x_s) 542 LD B,A 543 LD A,(.x_s+1) 544 LD C,A 545 SUB B 546 JR NC,ychk$ 547 LD A,C 548 LD (.x_s),A 549 LD A,B 550 LD (.x_s+1),A 551ychk$: 552 LD A,(.y_s) 553 LD B,A 554 LD A,(.y_s+1) 555 LD C,A 556 SUB B 557 JR NC,dbox$ 558 LD A,C 559 LD (.y_s),A 560 LD A,B 561 LD (.y_s+1),A 562dbox$: 563 LD A,(.x_s) 564 LD B,A 565 LD D,A 566 LD A,(.y_s) 567 LD C,A 568 LD A,(.y_s+1) 569 LD E,A 570 CALL .line 571 LD A,(.x_s+1) 572 LD B,A 573 LD D,A 574 LD A,(.y_s) 575 LD C,A 576 LD A,(.y_s+1) 577 LD E,A 578 CALL .line 579 LD A,(.x_s) 580 INC A 581 LD (.x_s),A 582 LD A,(.x_s+1) 583 DEC A 584 LD (.x_s+1),A 585 LD A,(.x_s) 586 LD B,A 587 LD A,(.x_s+1) 588 LD D,A 589 LD A,(.y_s) 590 LD C,A 591 LD E,A 592 CALL .line 593 LD A,(.x_s) 594 LD B,A 595 LD A,(.x_s+1) 596 LD D,A 597 LD A,(.y_s+1) 598 LD C,A 599 LD E,A 600 CALL .line 601 LD A,(.style) 602 OR A 603 RET Z 604 LD A,(.x_s) 605 LD B,A 606 LD A,(.x_s+1) 607 SUB B 608 RET C 609 LD A,(.y_s) 610 INC A 611 LD (.y_s),A 612 LD A,(.y_s+1) 613 DEC A 614 LD (.y_s+1),A 615 LD A,(.y_s) 616 LD B,A 617 LD A,(.y_s+1) 618 SUB B 619 RET C 620 621 .if 0 622 LD A,(.mod_col) ;Swap fore + back colours. 623 LD D,A 624 AND #0xF0 625 LD C,A ;Preserve Style 626 LD A,D 627 AND #0x0C 628 RRCA 629 RRCA 630 OR C ;Foreground->background + style 631 LD C,A 632 LD A,D 633 AND #0x03 634 RLCA 635 RLCA 636 OR C 637 LD (.mod_col),A 638 .else 639 LD A,(.fg_colour) 640 LD C,A 641 LD A,(.bg_colour) 642 LD (.fg_colour),A 643 LD A,C 644 LD (.bg_colour),A 645 .endif 646filllp$: 647 LD A,(.x_s) 648 LD B,A 649 LD A,(.x_s+1) 650 LD D,A 651 LD A,(.y_s) 652 LD C,A 653 LD E,A 654 CALL .line 655 LD A,(.y_s+1) 656 LD B,A 657 LD A,(.y_s) 658 CP B 659 JR Z,swap$ 660 INC A 661 LD (.y_s),A 662 JR filllp$ 663swap$: 664 .if 0 665 LD A,(.mod_col) ;Swap fore + back colours. 666 LD D,A 667 AND #0xF0 668 LD C,A ;Preserve Style 669 LD A,D 670 AND #0x0C 671 RRCA 672 RRCA 673 OR C ;Foreground->background + style 674 LD C,A 675 LD A,D 676 AND #0x03 677 RLCA 678 RLCA 679 OR C 680 LD (.mod_col),A 681 .else 682 LD A,(.fg_colour) 683 LD C,A 684 LD A,(.bg_colour) 685 LD (.fg_colour),A 686 LD A,C 687 LD (.bg_colour),A 688 .endif 689 RET 690 691 ;; Draw a line between (B,C) and (D,E) 692.line:: 693 LD A,C ;Calculate Delta Y 694 SUB E 695 JR NC,s1$ 696 CPL 697 INC A 698 699s1$: LD (.delta_y),A 700 LD H,A 701 702 LD A,B ;Calculate Delta X 703 SUB D 704 JR NC,s2$ 705 CPL 706 INC A 707 708s2$: LD (.delta_x),A 709 710 SUB H 711 JP C,y1 712 713 ;; Use Delta X 714 715 LD A,B 716 SUB D 717 JP NC,x2$ 718 719 LD A,C 720 SUB E 721 JR Z,x3$ 722 LD A,#0x00 723 JR NC,x3$ 724 LD A,#0xFF 725 JR x3$ 726 727x2$: 728 LD A,E 729 SUB C 730 JR Z,x2a$ 731 LD A,#0x00 732 JR NC,x2a$ 733 LD A,#0xFF 734 735x2a$: 736 LD B,D 737 LD C,E ;BC holds start X,Y 738x3$: 739 LD (.l_inc),A ;Store Y increment 740 LD HL,#.y_table 741 LD D,#0x00 742 LD E,C 743 ADD HL,DE 744 ADD HL,DE 745 LD A,(HL+) 746 LD H,(HL) 747 LD L,A 748 749 LD A,B 750 AND #0xf8 751 LD E,A 752 ADD HL,DE 753 ADD HL,DE 754 755 LD A,(.delta_y) 756 OR A 757 JP Z,.xonly 758 759 ;; Got to do it the hard way. 760 761 ; Calculate (2*deltay) -> dinc1 762 763 PUSH HL 764 LD H,#0x00 765 LD L,A 766 ADD HL,HL 767 LD A,H 768 LD (.dinc1),A 769 LD A,L 770 LD (.dinc1+1),A 771 772 ; Calculate (2*deltay)-deltax -> d 773 774 775 LD D,H 776 LD E,L 777 LD A,(.delta_x) 778 CPL 779 LD L,A 780 LD H,#0xFF 781 INC HL 782dx1$: 783 ADD HL,DE 784 LD A,H 785 LD (.l_d),A 786 LD A,L 787 LD (.l_d+1),A 788 789 ; Calculate (deltay-deltax)*2 -> dinc2 790 791 LD A,(.delta_x) 792 CPL 793 LD L,A 794 LD H,#0xFF 795 INC HL 796 LD A,(.delta_y) 797 LD D,#0x00 798 LD E,A 799 ADD HL,DE 800 ADD HL,HL 801 802 LD A,H 803 LD (.dinc2),A 804 LD A,L 805 LD (.dinc2+1),A 806 807 POP HL 808 809 .if 0 810 LD A,(.mod_col) 811 LD D,A 812 .endif 813 814 LD A,(.delta_x) 815 LD E,A 816 817 LD A,B 818 AND #7 819 ADD #<.drawing_bits_tbl ; Table of bits is located at 0x0070 820 LD C,A 821 LD B,#0x00 822 LD A,(BC) ; Get start bit 823 LD B,A 824 LD C,A 825 826xloop$: 827 RRC C 828 LD A,(.l_d) 829 BIT 7,A 830 JR Z,ychg$ 831 PUSH DE 832 BIT 7,C 833 JR Z,nbit$ 834 LD A,B 835 CPL 836 LD C,A 837 CALL .wrbyte 838 DEC HL 839 LD C,#0x80 840 LD B,C 841nbit$: 842 LD A,(.l_d+1) 843 LD D,A 844 LD A,(.dinc1+1) 845 ADD D 846 LD (.l_d+1),A 847 LD A,(.l_d) 848 LD D,A 849 LD A,(.dinc1) 850 ADC D 851 LD (.l_d),A 852 POP DE 853 JR nchg$ 854ychg$: 855 PUSH DE 856 PUSH BC 857 LD A,B 858 CPL 859 LD C,A 860 CALL .wrbyte 861 LD A,(.l_inc) 862 OR A 863 JR Z,ydown$ 864 INC HL 865 LD A,L 866 AND #0x0F 867 JR NZ,bound$ 868 LD DE,#0x0130 869 ADD HL,DE ;Correct screen address 870 JR bound$ 871ydown$: 872 DEC HL 873 DEC HL 874 DEC HL 875 LD A,L 876 AND #0x0F 877 XOR #0x0E 878 JR NZ,bound$ 879 LD DE,#0xFED0 880 ADD HL,DE ;Correct screen address 881bound$: 882 LD A,(.l_d+1) 883 LD D,A 884 LD A,(.dinc2+1) 885 ADD D 886 LD (.l_d+1),A 887 LD A,(.l_d) 888 LD D,A 889 LD A,(.dinc2) 890 ADC D 891 LD (.l_d),A 892 POP BC 893 LD B,C 894 POP DE 895nchg$: 896 BIT 7,C 897 JR Z,nadj$ 898 PUSH DE 899 LD DE,#0x0010 900 ADD HL,DE ;Correct screen address 901 POP DE 902 LD B,C 903nadj$: 904 LD A,B 905 OR C 906 LD B,A 907 DEC E 908 JP NZ,xloop$ 909 LD A,B 910 CPL 911 LD C,A 912 JP .wrbyte 913 914.xonly:: 915 ;; Draw accelerated horizontal line 916 .if 0 917 ;; xxx needed? 918 LD A,(.mod_col) 919 LD D,A 920 .endif 921 922 LD A,(.delta_x) 923 LD E,A 924 INC E 925 926 LD A,B ;check X 927 AND #7 ;just look at bottom 3 bits 928 JR Z,2$ 929 PUSH HL 930 ADD #<.drawing_bits_tbl ;Table of bits is located at 0x0070 931 LD L,A 932 LD H,#0x00 933 LD C,(HL) 934 POP HL 935 XOR A ;Clear A 9361$: RRCA ;Shift data right 1 937 OR C 938 DEC E 939 JR Z,3$ 940 BIT 0,A 941 JR Z,1$ 942 JR 3$ 9432$: 944 LD A,E 945 DEC A 946 AND #0xF8 947 JR Z,4$ 948 JR 8$ 9493$: 950 LD B,A 951 CPL 952 LD C,A 953 PUSH DE 954 CALL .wrbyte 955 LD DE,#0x0F 956 ADD HL,DE ;Correct screen address 957 POP DE 958 9598$: LD A,E 960 OR A 961 RET Z 962 AND #0xF8 963 JR Z,4$ 964 965 XOR A 966 LD C,A 967 CPL 968 LD B,A 969 970 PUSH DE 971 CALL .wrbyte 972 LD DE,#0x0F 973 ADD HL,DE ;Correct screen address 974 POP DE 975 LD A,E 976 SUB #8 977 RET Z 978 LD E,A 979 JR 8$ 980 9814$: LD A,#0x80 9825$: DEC E 983 JR Z,6$ 984 SRA A 985 JR 5$ 9866$: LD B,A 987 CPL 988 LD C,A 989 JP .wrbyte 990 991 ;; Use Delta Y 992y1: 993 LD A,C 994 SUB E 995 JP NC,y2$ 996 997 LD A,B 998 SUB D 999 JR Z,y3$ 1000 LD A,#0x00 1001 JR NC,y3$ 1002 LD A,#0xFF 1003 JR y3$ 1004 1005y2$: 1006 LD A,C 1007 SUB E 1008 JR Z,y2a$ 1009 LD A,#0x00 1010 1011; JR NC,y2a$ ; old code; fix draw to up-left below 1012; LD A,#0xFF 1013 1014 LD L,A ; invert delta if x1 less than x2 1015 LD A,B 1016 SUB D 1017 LD A,L 1018 JR C,y2a$ 1019 CPL 1020 1021y2a$: 1022 LD B,D 1023 LD C,E ;BC holds start X,Y 1024 1025y3$: 1026 LD (.l_inc),A ;Store X increment 1027 LD HL,#.y_table 1028 LD D,#0x00 1029 LD E,C 1030 ADD HL,DE 1031 ADD HL,DE 1032 LD A,(HL+) 1033 LD H,(HL) 1034 LD L,A 1035 1036 LD A,B 1037 AND #0xf8 1038 LD E,A 1039 ADD HL,DE 1040 ADD HL,DE 1041 1042 .if 0 1043 ;; Trashed by later instructions 1044 LD A,(.mod_col) 1045 LD D,A 1046 .endif 1047 1048 LD A,(.delta_y) 1049 LD E,A 1050 INC E 1051 1052 LD A,(.delta_x) 1053 OR A 1054 JP Z,.yonly 1055 1056 ;; Got to do it the hard way. 1057 1058 ; Calculate (2*deltax) -> dinc1 1059 1060 PUSH HL 1061 LD H,#0x00 1062 LD L,A 1063 ADD HL,HL 1064 LD A,H 1065 LD (.dinc1),A 1066 LD A,L 1067 LD (.dinc1+1),A 1068 1069 ; Calculate (2*deltax)-deltay -> d 1070 1071 1072 LD D,H 1073 LD E,L 1074 LD A,(.delta_y) 1075 CPL 1076 LD L,A 1077 LD H,#0xFF 1078 INC HL 1079dy1$: 1080 ADD HL,DE 1081 LD A,H 1082 LD (.l_d),A 1083 LD A,L 1084 LD (.l_d+1),A 1085 1086 ; Calculate (deltax-deltay)*2 -> dinc2 1087 1088 LD A,(.delta_y) 1089 CPL 1090 LD L,A 1091 LD H,#0xFF 1092 INC HL 1093 LD A,(.delta_x) 1094 LD D,#0x00 1095 LD E,A 1096 ADD HL,DE 1097 ADD HL,HL 1098 1099 LD A,H 1100 LD (.dinc2),A 1101 LD A,L 1102 LD (.dinc2+1),A 1103 1104 POP HL 1105 1106 .if 0 1107 ;; xxx Not used? 1108 LD A,(.mod_col) 1109 LD D,A 1110 .endif 1111 1112 LD A,(.delta_y) 1113 LD E,A 1114 1115 LD A,B 1116 AND #7 1117 ADD #<.drawing_bits_tbl ; Table of bits is located at 0x0070 1118 LD C,A 1119 LD B,#0x00 1120 LD A,(BC) ; Get start bit 1121 LD B,A 1122 LD C,A 1123 1124yloop$: 1125 PUSH DE 1126 PUSH BC 1127 LD A,B 1128 CPL 1129 LD C,A 1130 CALL .wrbyte 1131 INC HL 1132 LD A,L 1133 AND #0x0F 1134 JR NZ,nybound$ 1135 LD DE,#0x0130 1136 ADD HL,DE ;Correct screen address 1137nybound$: 1138 POP BC 1139 LD A,(.l_d) 1140 BIT 7,A 1141 JR Z,xchg$ 1142 LD A,(.l_d+1) 1143 LD D,A 1144 LD A,(.dinc1+1) 1145 ADD D 1146 LD (.l_d+1),A 1147 LD A,(.l_d) 1148 LD D,A 1149 LD A,(.dinc1) 1150 ADC D 1151 LD (.l_d),A 1152 JR nchgy$ 1153xchg$: 1154 LD A,(.l_inc) 1155 OR A 1156 JR NZ,yright$ 1157 RLC B 1158 BIT 0,B 1159 JR Z,boundy$ 1160 LD DE,#0xFFF0 1161 ADD HL,DE ;Correct screen address 1162 JR boundy$ 1163yright$: 1164 RRC B 1165 BIT 7,B 1166 JR Z,boundy$ 1167 LD DE,#0x0010 1168 ADD HL,DE ;Correct screen address 1169boundy$: 1170 LD A,(.l_d+1) 1171 LD D,A 1172 LD A,(.dinc2+1) 1173 ADD D 1174 LD (.l_d+1),A 1175 LD A,(.l_d) 1176 LD D,A 1177 LD A,(.dinc2) 1178 ADC D 1179 LD (.l_d),A 1180nchgy$: 1181 POP DE 1182 DEC E 1183 JR NZ,yloop$ 1184 LD A,B 1185 CPL 1186 LD C,A 1187 JP .wrbyte 1188 1189.yonly:: 1190 ;; Draw accelerated vertical line 1191 LD A,B ;check X 1192 AND #7 ;just look at bottom 3 bits 1193 PUSH HL 1194 ADD #<.drawing_bits_tbl ;Table of bits is located at 0x0070 1195 LD L,A 1196 LD H,#0x00 1197 LD A,(HL) ;Get mask bit 1198 POP HL 1199 LD B,A 1200 CPL 1201 LD C,A 1202 12031$: PUSH DE 1204 CALL .wrbyte 1205 INC HL ;Correct screen address 1206 LD A,L 1207 AND #0x0F 1208 JR NZ,2$ 1209 LD DE,#0x0130 1210 ADD HL,DE 12112$: POP DE 1212 DEC E 1213 RET Z 1214 JR 1$ 1215 1216 ;; Draw a point at (B,C) with mode and color D 1217.plot:: 1218 1219 LD HL,#.y_table 1220 LD D,#0x00 1221 LD E,C 1222 ADD HL,DE 1223 ADD HL,DE 1224 LD A,(HL+) 1225 LD H,(HL) 1226 LD L,A 1227 1228 LD A,B 1229 AND #0xf8 1230 LD E,A 1231 ADD HL,DE 1232 ADD HL,DE 1233 1234 LD A,B 1235 1236 AND #7 1237 ADD #<.drawing_bits_tbl ; Table of bits is located at 0x0070 1238 LD C,A 1239 LD B,#0x00 1240 LD A,(BC) 1241 LD B,A 1242 CPL 1243 LD C,A 1244 1245.wrbyte:: 1246 .if 0 1247 LD A,(.mod_col) ; Restore color and mode 1248 LD D,A 1249 1250 BIT 5,D 1251 JR NZ,10$ 1252 BIT 6,D 1253 JR NZ,20$ 1254 BIT 7,D 1255 JR NZ,30$ 1256 .else 1257 LD A,(.fg_colour) 1258 LD D,A 1259 LD A,(.draw_mode) 1260 CP #.M_OR 1261 JR Z,10$ 1262 CP #.M_XOR 1263 JR Z,20$ 1264 CP #.M_AND 1265 JR Z,30$ 1266 .endif 1267 1268 ; Fall through to SOLID by default 12691$: 1270 ;; Solid 1271 LD E,B 1272 .if 0 1273 BIT 2,D 1274 .else 1275 BIT 0,D 1276 .endif 1277 JR NZ,2$ 1278 PUSH BC 1279 LD B,#0x00 12802$: 1281 .if 0 1282 BIT 3,D 1283 .else 1284 BIT 1,D 1285 .endif 1286 JR NZ,3$ 1287 LD E,#0x00 12883$: 1289 WAIT_STAT 1290 1291 LD A,(HL) 1292 AND C 1293 OR B 1294 LD (HL+),A 1295 1296 LD A,(HL) 1297 AND C 1298 OR E 1299 LD (HL),A 1300 LD A,B 1301 OR A 1302 RET NZ 1303 POP BC 1304 RET 1305 130610$: 1307 ;; Or 1308 LD C,B 1309 .if 0 1310 BIT 2,D 1311 .else 1312 BIT 0,D 1313 .endif 1314 JR NZ,11$ 1315 LD B,#0x00 131611$: 1317 .if 0 1318 BIT 3,D 1319 .else 1320 BIT 1,D 1321 .endif 1322 JR NZ,12$ 1323 LD C,#0x00 132412$: 1325 WAIT_STAT 1326 1327 LD A,(HL) 1328 OR B 1329 LD (HL+),A 1330 1331 LD A,(HL) 1332 OR C 1333 LD (HL),A 1334 RET 1335 133620$: 1337 ;; Xor 1338 LD C,B 1339 .if 0 1340 BIT 2,D 1341 .else 1342 BIT 0,D 1343 .endif 1344 JR NZ,21$ 1345 LD B,#0x00 134621$: 1347 .if 0 1348 BIT 3,D 1349 .else 1350 BIT 1,D 1351 .endif 1352 JR NZ,22$ 1353 LD C,#0x00 135422$: 1355 WAIT_STAT 1356 1357 LD A,(HL) 1358 XOR B 1359 LD (HL+),A 1360 1361 LD A,(HL) 1362 XOR C 1363 LD (HL),A 1364 RET 1365 136630$: 1367 ;; And 1368 LD B,C 1369 .if 0 1370 BIT 2,D 1371 .else 1372 BIT 0,D 1373 .endif 1374 JR Z,31$ 1375 LD B,#0xFF 137631$: 1377 .if 0 1378 BIT 3,D 1379 .else 1380 BIT 1,D 1381 .endif 1382 JR Z,32$ 1383 LD C,#0xFF 138432$: 1385 WAIT_STAT 1386 1387 LD A,(HL) 1388 AND B 1389 LD (HL+),A 1390 1391 LD A,(HL) 1392 AND C 1393 LD (HL),A 1394 RET 1395 1396 ;; Get color of pixel at point (B,C) returns in A 1397.getpix:: 1398 LD HL,#.y_table 1399 LD D,#0x00 1400 LD E,C 1401 ADD HL,DE 1402 ADD HL,DE 1403 LD A,(HL+) 1404 LD H,(HL) 1405 LD L,A 1406 1407 LD A,B 1408 AND #0xf8 1409 LD E,A 1410 ADD HL,DE 1411 ADD HL,DE 1412 1413 LD A,B 1414 1415 AND #7 1416 ADD #<.drawing_bits_tbl ; Table of bits is located at 0x0070 1417 LD C,A 1418 LD B,#0x00 1419 LD A,(BC) 1420 LD C,A 1421 1422 WAIT_STAT 1423 1424 LD A,(HL+) 1425 LD D,A 1426 LD A,(HL+) 1427 LD E,A 1428 LD B,#0 1429 LD A,D 1430 AND C 1431 JR Z,1$ 1432 SET 0,B 14331$: LD A,E 1434 AND C 1435 JR Z,2$ 1436 SET 1,B 14372$: LD E,B 1438 RET 1439 1440 ;; Write character C 1441.wrtchr:: 1442 LD HL,#.y_table 1443 LD D,#0x00 1444 LD A,(.ty) 1445 RLCA 1446 RLCA 1447 RLCA 1448 LD E,A 1449 ADD HL,DE 1450 ADD HL,DE 1451 LD A,(HL+) 1452 LD B, A 1453 LD H,(HL) 1454 LD L,B 1455 1456 LD A,(.tx) 1457 RLCA 1458 RLCA 1459 RLCA 1460 LD E,A 1461 ADD HL,DE 1462 ADD HL,DE 1463 1464 LD A,C 1465 LD B,H 1466 LD C,L 1467 1468 LD H,D 1469 LD L,A 1470 ADD HL,HL 1471 ADD HL,HL 1472 ADD HL,HL 1473 1474 .if 0 1475 LD DE,#.tp1 1476 .else 1477 .globl _font_ibm_fixed_tiles 1478 1479 LD DE,#_font_ibm_fixed_tiles 1480 .endif 1481 1482 ADD HL,DE 1483 1484 LD D,H 1485 LD E,L 1486 LD H,B 1487 LD L,C 1488 1489 .if 0 1490 LD A,(.mod_col) 1491 LD C,A 1492 .else 1493 LD A,(.fg_colour) 1494 LD C,A 1495 .endif 14961$: 1497 LD A,(DE) 1498 INC DE 1499 PUSH DE 1500 1501 .if 1 1502 PUSH HL 1503 LD HL,#.bg_colour 1504 LD L,(HL) 1505 .endif 1506 1507 LD B,A 1508 XOR A 1509 .if 0 1510 BIT 0,C 1511 .else 1512 BIT 0,L 1513 .endif 1514 JR Z,2$ 1515 CPL 15162$: OR B 1517 .if 0 1518 BIT 2,C 1519 .else 1520 BIT 0,C 1521 .endif 1522 JR NZ,3$ 1523 XOR B 15243$: LD D,A 1525 XOR A 1526 .if 0 1527 BIT 1,C 1528 .else 1529 BIT 1,L 1530 .endif 1531 JR Z,4$ 1532 CPL 15334$: OR B 1534 .if 0 1535 BIT 3,C 1536 .else 1537 BIT 1,C 1538 .endif 1539 JR NZ,5$ 1540 XOR B 15415$: 1542 LD E,A 1543 .if 1 1544 POP HL 1545 .endif 1546 1547 WAIT_STAT 1548 1549 LD A,D 1550 LD (HL+),A 1551 LD A,E 1552 LD (HL+),A 1553 POP DE 1554 LD A,L 1555 AND #0x0F 1556 JR NZ,1$ 1557 RET 1558 1559_gotogxy:: 1560 LDA HL,2(SP) ; Skip return address 1561 LD A,(HL+) ; A = x 1562 LD (.tx),A 1563 LD A,(HL+) ; A = y 1564 LD (.ty),A 1565 1566 RET 1567 1568_wrtchr:: 1569 PUSH BC 1570 1571 LD A,(.mode) 1572 CP #.G_MODE 1573 CALL NZ,.gmode 1574 1575 LDA HL,4(SP) ; Skip return address and registers 1576 LD A,(HL) 1577 LD C,A ; C = Char to print 1578 1579 CALL .wrtchr 1580 CALL .adv_gcurs 1581 1582 POP BC 1583 RET 1584 1585_getpix:: 1586 PUSH BC 1587 1588 LDA HL,4(SP) ; Skip return address and registers 1589 LD A,(HL+) ; B = x 1590 LD B,A 1591 LD A,(HL+) ; C = y 1592 LD C,A 1593 1594 CALL .getpix 1595 1596 POP BC 1597 RET 1598 1599_circle:: 1600 PUSH BC 1601 1602 LD A,(.mode) 1603 CP #.G_MODE 1604 CALL NZ,.gmode 1605 1606 LDA HL,4(SP) ; Skip return address and registers 1607 LD A,(HL+) ; B = x 1608 LD B,A 1609 LD A,(HL+) ; C = y 1610 LD C,A 1611 LD A,(HL+) ; D = Radius 1612 LD D,A 1613 LD A,(HL) 1614 LD (.style),A 1615 1616 CALL .circle 1617 1618 POP BC 1619 RET 1620 1621_box:: 1622 PUSH BC 1623 1624 LD A,(.mode) 1625 CP #.G_MODE 1626 CALL NZ,.gmode 1627 1628 LDA HL,4(SP) ; Skip return address and registers 1629 LD A,(HL+) ; B = x1 1630 LD (.x_s),A 1631 LD A,(HL+) ; C = y1 1632 LD (.y_s),A 1633 LD A,(HL+) ; D = x2 1634 LD (.x_s+1),A 1635 LD A,(HL+) ; E = y2 1636 LD (.y_s+1),A 1637 LD A,(HL) 1638 LD (.style),A 1639 CALL .box 1640 POP BC 1641 RET 1642 1643_line:: 1644 PUSH BC 1645 1646 LD A,(.mode) 1647 CP #.G_MODE 1648 CALL NZ,.gmode 1649 1650 LDA HL,4(SP) ; Skip return address and registers 1651 LD A,(HL+) ; B = x1 1652 LD B,A 1653 LD A,(HL+) ; C = y1 1654 LD C,A 1655 LD A,(HL+) ; D = x2 1656 LD D,A 1657 LD A,(HL+) ; E = y2 1658 LD E,A 1659 1660 CALL .line 1661 1662 POP BC 1663 RET 1664 1665_plot_point:: 1666 PUSH BC 1667 1668 LD A,(.mode) 1669 CP #.G_MODE 1670 CALL NZ,.gmode 1671 1672 LDA HL,4(SP) ; Skip return address and registers 1673 LD A,(HL+) ; B = x 1674 LD B,A 1675 LD A,(HL+) ; C = y 1676 LD C,A 1677 1678 CALL .plot 1679 1680 POP BC 1681 RET 1682 1683 ;; Old, compatible version of plot() 1684_plot:: 1685 PUSH BC 1686 1687 LD A,(.mode) 1688 CP #.G_MODE 1689 CALL NZ,.gmode 1690 1691 LDA HL,4(SP) ; Skip return address and registers 1692 LD A,(HL+) ; B = x 1693 LD B,A 1694 LD A,(HL+) ; C = y 1695 LD C,A 1696 LD A,(HL+) ; colour 1697 LD (.fg_colour),A 1698 LD A,(HL+) ; mode 1699 LD (.draw_mode),A 1700 1701 CALL .plot 1702 1703 POP BC 1704 RET 1705 1706_switch_data:: ; Non Banked as pointer 1707 PUSH BC 1708 1709 LD A,(.mode) 1710 CP #.G_MODE 1711 CALL NZ,.gmode 1712 1713 LDA HL,4(SP) ; Skip return address and registers 1714 LD A,(HL+) ; B = x 1715 LD B,A 1716 LD A,(HL+) ; C = y 1717 LD C,A 1718 LD A,(HL+) ; DE = src 1719 LD E,A 1720 LD A,(HL+) 1721 LD D,A 1722 LD A,(HL+) ; HL = dst 1723 LD H,(HL) 1724 LD L,A 1725 1726 CALL .switch_data 1727 1728 POP BC 1729 RET 1730 1731 1732_draw_image:: ; Non banked as pointer 1733 PUSH BC 1734 1735 LD A,(.mode) 1736 CP #.G_MODE 1737 CALL NZ,.gmode 1738 1739 LDA HL,4(SP) ; Skip return address and registers 1740 LD A,(HL+) ; HL = data 1741 LD C,A 1742 LD B,(HL) 1743 1744 CALL .draw_image 1745 1746 POP BC 1747 RET 1748 1749.y_table:: 1750 .word 0x8100,0x8102,0x8104,0x8106,0x8108,0x810A,0x810C,0x810E 1751 .word 0x8240,0x8242,0x8244,0x8246,0x8248,0x824A,0x824C,0x824E 1752 .word 0x8380,0x8382,0x8384,0x8386,0x8388,0x838A,0x838C,0x838E 1753 .word 0x84C0,0x84C2,0x84C4,0x84C6,0x84C8,0x84CA,0x84CC,0x84CE 1754 .word 0x8600,0x8602,0x8604,0x8606,0x8608,0x860A,0x860C,0x860E 1755 .word 0x8740,0x8742,0x8744,0x8746,0x8748,0x874A,0x874C,0x874E 1756 .word 0x8880,0x8882,0x8884,0x8886,0x8888,0x888A,0x888C,0x888E 1757 .word 0x89C0,0x89C2,0x89C4,0x89C6,0x89C8,0x89CA,0x89CC,0x89CE 1758 .word 0x8B00,0x8B02,0x8B04,0x8B06,0x8B08,0x8B0A,0x8B0C,0x8B0E 1759 .word 0x8C40,0x8C42,0x8C44,0x8C46,0x8C48,0x8C4A,0x8C4C,0x8C4E 1760 .word 0x8D80,0x8D82,0x8D84,0x8D86,0x8D88,0x8D8A,0x8D8C,0x8D8E 1761 .word 0x8EC0,0x8EC2,0x8EC4,0x8EC6,0x8EC8,0x8ECA,0x8ECC,0x8ECE 1762 .word 0x9000,0x9002,0x9004,0x9006,0x9008,0x900A,0x900C,0x900E 1763 .word 0x9140,0x9142,0x9144,0x9146,0x9148,0x914A,0x914C,0x914E 1764 .word 0x9280,0x9282,0x9284,0x9286,0x9288,0x928A,0x928C,0x928E 1765 .word 0x93C0,0x93C2,0x93C4,0x93C6,0x93C8,0x93CA,0x93CC,0x93CE 1766 .word 0x9500,0x9502,0x9504,0x9506,0x9508,0x950A,0x950C,0x950E 1767 .word 0x9640,0x9642,0x9644,0x9646,0x9648,0x964A,0x964C,0x964E