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