1     0000              	;; Note: JP in this program could just as easily be JR,
2     0000              	;; but we use JP to force relocations to be necessary.
3     0000              	;; It is also just slightly faster.
4     0000              
5     0000              	;; This lets RUN work after program exit, it is simply
6     0000              	;; the BASIC internal code for:
7     0000              	;; 1 Z%=CALL(<start>%) <end program>
8     0000              basic_prefix:
9     0000  10 01 00 83 C1 F1 5A 00 BB C7 
                        	defb 10h,01h,00h,83h,0c1h,0f1h,5ah,00h,0bbh,0c7h
10    000A  11 00       	defw _start
11    000C  CE 3A B7 0D 01 
                        	defb 0ceh,03ah,0b7h,0dh,01h
12    0011              
13    0011              	defc IYBASE=65046
14    0011              	defc CLK=65008, IYCLK=CLK-IYBASE
15    0011              	defc CTRLC=65031, IYCTRLC=CTRLC-IYBASE
16    0011              	defc CURY=65011, IYCURY=CURY-IYBASE
17    0011              	defc CURX=65012, IYCURX=CURX-IYBASE
18    0011              
19    0011              	global _start
20    0011              _start:
21    0011              	;; BASIC doesn't like these mucked with...
22    0011              	;push ix
23    0011  FD E5       	push iy
24    0013  FD 21 16 FE 	ld iy,IYBASE		; Should already be true...
25    0017              
26    0017  3A 7A 03    	ld a,(884+3*2)		; 40 in 40-col mode, 80 in 80-col mode
27    001A  F5          	push af
28    001B              
29    001B              	;; 40 column mode
30    001B  DB 03       	in a,(3)
31    001D              
32    001D              	;; Clear screen and set up graphics mode
33    001D  21 74 03    	ld hl,884		; Line table in BASIC ROM
34    0020  06 18       	ld b,24			; Line count
35    0022              clrscrn:
36    0022  5E          	ld e,(hl)
37    0023  2C          	inc l			; HL goes from 0374h to 03a2h so this is safe
38    0024  56          	ld d,(hl)
39    0025  2C          	inc l
40    0026              
41    0026  E5          	push hl
42    0027  C5          	push bc
43    0028              
44    0028  3E 17       	ld a,017h		; GWHT
45    002A  12          	ld (de),a
46    002B  1C          	inc e			; Cannot overflow
47    002C  6B          	ld l,e
48    002D  62          	ld h,d
49    002E  36 20       	ld (hl),' '
50    0030  1C          	inc e
51    0031  01 26 00    	ld bc,38
52    0034  ED B0       	ldir
53    0036              
54    0036  C1          	pop bc
55    0037  E1          	pop hl
56    0038  10 E8       	djnz clrscrn
57    003A              
58    003A              	;; Here begins the actual drawing.  First, we need two
59    003A              	;; pseudorandom numbers between 1 and 8.
60    003A              draw_loop:
61    003A  ED 5F       	ld a,r			; Good enough probably
62    003C  1F          	rra
63    003D  1F          	rra
64    003E  1F          	rra
65    003F  E6 07       	and 7
66    0041  3C          	inc a
67    0042  47          	ld b,a			; Row-increment
68    0043  ED 5F       	ld a,r
69    0045  E6 07       	and 7
70    0047  3C          	inc a
71    0048  4F          	ld c,a			; Column-increment
72    0049              
73    0049              	;; Row loop header
74    0049  21 74 03    	ld hl,884
75    004C  16 00       	ld d,0x0		; D = pixel row inside row -> HL
76    004E              
77    004E              row_loop:
78    004E  7A          	ld a,d
79    004F  80          	add b
80    0050              rla:				; Advance to the appropriate pixel row
81    0050  57          	ld d,a
82    0051  D6 03       	sub 3
83    0053  DA 5B 00    	jp c,rla_done
84    0056  2C          	inc l
85    0057  2C          	inc l
86    0058  C3 50 00    	jp rla
87    005B              rla_done:
88    005B  7D          	ld a,l
89    005C  FE A4       	cp (884 + 2*24) & 255
90    005E  D2 91 00    	jp nc,row_done
91    0061              
92    0061              	;; Column loop header
93    0061  E5          	push hl
94    0062  7E          	ld a,(hl)
95    0063  2C          	inc l
96    0064  66          	ld h,(hl)
97    0065  6F          	ld l,a
98    0066              	; HL -> current character row
99    0066              
100   0066  1E 02       	ld e,2			; Pixel column
101   0068              col_loop:
102   0068  C5          	push bc
103   0069  E5          	push hl
104   006A              
105   006A  7B          	ld a,e
106   006B  81          	add c			; C <- 0
107   006C  5F          	ld e,a
108   006D  1F          	rra			; C <- bit 0
109   006E              	;;  A = byte offset
110   006E  F5          	push af
111   006F  FE 28        	cp 40
112   0071  D2 8A 00    	jp nc,col_done
113   0074  85          	add l			; Will not overflow so it is OK
114   0075  6F          	ld l,a
115   0076  F1          	pop af
116   0077  7A          	ld a,d
117   0078  17          	rla
118   0079  FE 05       	cp 5
119   007B  DE FE       	sbc -2			; bit 5 -> bit 6; add one
120   007D              	; A = bit number to flip + 1
121   007D  47          	ld b,a
122   007E  AF          	xor a
123   007F  37          	scf			; Insert a 1 bit on first iteration
124   0080              shift:
125   0080  17          	rla
126   0081  10 FD       	djnz shift
127   0083              
128   0083              	; Flip the relevant bit
129   0083  AE          	xor (hl)
130   0084  77          	ld (hl),a
131   0085              
132   0085  E1          	pop hl
133   0086  C1          	pop bc
134   0087  C3 68 00    	jp col_loop
135   008A              
136   008A              col_done:
137   008A  F1          	pop af
138   008B  E1          	pop hl
139   008C  C1          	pop bc
140   008D  E1          	pop hl
141   008E  C3 4E 00    	jp row_loop
142   0091              
143   0091              row_done:
144   0091              	;; Wait for 1/2 second unless the user presses Ctrl-C
145   0091  06 19       	ld b,25
146   0093              
147   0093              wait_1:
148   0093  FD 7E DA    	ld a,(iy+IYCLK)
149   0096              wait_2:
150   0096  76          	halt			; Let the CPU rest until an interrupt
151   0097  FD CB F1 7E 	bit 7,(iy+IYCTRLC)
152   009B  C2 A9 00    	jp nz,exit
153   009E  FD BE DA    	cp (iy+IYCLK)
154   00A1  CA 96 00    	jp z,wait_2
155   00A4  10 ED       	djnz wait_1
156   00A6  C3 3A 00    	jp draw_loop
157   00A9              
158   00A9              exit:
159   00A9  FD CB F1 BE 	res 7,(iy+IYCTRLC)	; Clear Ctrl-C
160   00AD  F1          	pop af
161   00AE  FE 28       	cp 40
162   00B0  CA B5 00    	jp z,was_40
163   00B3  DB 04       	in a,(4)		; Return to 80-column mode
164   00B5              was_40:
165   00B5  FD 36 DE 00 	ld (iy+IYCURX),0	; New cursor column
166   00B9  FD 36 DD 17 	ld (iy+IYCURY),23	; New cursor row
167   00BD              
168   00BD  FD E1       	pop iy
169   00BF              	;pop ix
170   00BF              
171   00BF  C9          	ret
172   00C0              
