numlevels:	equ	endlevs-levorder
	;
org 32698
	ret	;stop auto ULAplus
	;
org 33766
	call nextlevelscreen
	jp 33635
	;
org 31192
	call resetAGDvars
	;
org 31226
	call killplayer
	;
org 25300
start:	
	call setints
	xor a
	ld (level),a
	ld hl,triestore
	ld de,tries
	ld bc,4
	ldir
introscreen:
	call setupintroscreen
	ld ix,introstring0
	call printstring
introloop:
	halt
	halt
	ld hl,(ospradd)		;delete tilesprout
	call deletetile
	call dohappysprout
	ld hl,loopcounter
	inc (hl)
	ld a,247		;check for 
	in a,(254)
	call ikeypressed
	jr c,introscreen
	jr introloop
	;
setints:
	ld de,(49152)
	call setbank1
	ld a,(49152)
	cp e
	push af
	call setbank0
	pop af
	ret z
	call makevectortable
	call setAYint
	ret
	;
makevectortable:
	ld hl,59648	;233 next available high byte
	ld de,59649
	ld (hl),232	;interupt routine needs to be at 
	ld bc,256
	ldir
	ld hl,intstore
	ld de,59624	;at high byte 232 + 232
	ldi
	ldi
	ldi
	ret
	;
interrupt_routine:
	push af
	push bc
	push de
	push hl
	push ix
	ex af,af'		;Bugfix: VTII player uses AF' which wasn't preserved
	push af			;Removed PUSH/POP IY since IY isn't used by the player
	call setbank1		;Changed to use CALL for bank switching
intpok:	call 49157		;Enabled the music
	call setbank0
	call 56
	pop af
	ex af,af'
	pop ix
	pop hl
	pop de
	pop bc
	pop af
	ei
	ret
	;
intstore:	jp interrupt_routine
	;
setAYint:
	di
	ld a,233
	ld i,a		;i jumps to vector table at 59648
	im 2
	call setbank1	;Added bank switching here
	call 49152	;activate VT player
	call setbank0
	ei
	ret
	;
setbank1		;Bank switching routines. This one sets 128K bank 1
	ld a,17
	DEFB 1		;Falls through to LD BC,32765
setbank0
	ld a,16		;Sets 128K bank 0
	ld bc,32765
	ld (23388),a	;Keep the value of 32765 (just in case)
	out (c),a
	ret
;
	;
resetAGDvars:		;sets akk AGD variables A - T to 0
	ld hl,32029	;variable 'A'
	ld b,20
rvlp:	ld (hl),0
	inc hl
	djnz rvlp
	ret
	;
ikeypressed:
	rra
	jp nc,gamestart		;AGD game start
	rra
	jp nc,instructions
	rra
	jp nc,refinekeys;definekeys
	xor a	;clear carry
donowt:	ret
	;
gamestart:
	call keytapsound
	call nlent	;show screen but not inc level
	call 32000
	scf	;so return to introscreen knows what to do
	ret
	;
killplayer:
	call inctries
	ld a,86
	call paperfill0
	call crashdrummy
	ld a,56
	call paperfill0
	ld hl,falhaATTR
	ld de,22528+224+3
	ld b,8
kplp:	push bc
	ld bc,26
	ldir
	ex de,hl
	ld bc,32-26
	add  hl,bc
	ex de,hl
	pop bc
	djnz kplp
	call tvnoise
	ld a,7
	call paperfill0
	call cls
	ret
	;
inctries:
	ld a,253
	ld (notry),a	;enable printing of 'TRIES'
	ld hl,tries+3
	ld b,3
itlp:	inc (hl)
	ld a,(hl)
	cp 58
	ret c
	ld (hl),'0'
	dec hl
	djnz itlp
	ret
	;
nextlevelscreen:
	ld a,65
	call paperfill0
	ld h,100
	call tzlp
	call crashdrummy
	ld a,(level)
	inc a
	ld (level),a
	cp numlevels
	jp nc,finscreen
nlent:	call resetAGDvars
	call getlevstring
	ld ix,startstring
	call printstring
	call waitkey
	call keytapsound
	call getlevel
	ret
	;
getlevel:
	ld hl,(level)
	ld h,0
	ld bc,levorder
	add hl,bc
	ld a,(hl)
	ld (32027),a	;tell AGD which level we want to play
	ret
	;
getlevstring:	;get correct ASCII for level
	ld a,(level)
	add a,a
	ld h,0
	ld l,a
	ld bc,levstrings
	add hl,bc
	ld de,levstr
	ldi
	ldi
	ret
	;
levorder:	db	2,16,17,0,3,1,4,15,5,7,12,6,9,8,10,11,13,14
endlevs:
	;
startstring:
	db	246	;cls
	db	249,7	;normal font colour
	db	248,69,68,68,4	;big font colour
	db	254,5		;very big print
	db	244,0		;border
	db	245,68		;paper
	db	253,0,8
	db	'NiVEL '
levstr:	db	'  '
notry:	db	255,3,14	;NB 253 gets poked in here when there are fails
	db	254,4		;very big print
	db	248,66,2,68,4	;big font colour
	db	'FALHAS:'
tries:	db	'0000'
	db	255
	;
triestore:	db	'0000'
	;
level:	db	0
	;
levstrings:
	db	'1 2 3 4 5 6 7 8 9 101112131415161718'
	;
trybyte:	db	0
	;
tvnoise:
	ld hl,0
tvp:	ld b,64
tvlp1:	push bc
	ld de,16384
	ld b,192
tvlp0:	push bc
	ld bc,32
	ldir
	ld a,(hl)
	and 24
	out (254),a
	pop bc
	djnz tvlp0
	ld a,h
	and 31
	ld h,a
	pop bc
	djnz tvlp1
	ld a,16
	ld (tvp+1),a
	ld a,(trybyte)
	inc a
	ld (trybyte),a
	cp 16
	ret c
	dec a
	ld (trybyte),a
	ld a,6		;shorten the death time to avoid boredom
	ld (tvp+1),a
	ret
	;
	;
refinekeys:
	ld ix,keystring0
	call printstring
	call crashdrummy
	ld hl,35339	;7 keys are stored here
	ld b,7		;number of keys
rklp:	ld (hl),255	;reset logged keys
	inc hl
	djnz rklp
	ld ix,keystring
	ld hl,35339
	ld b,2		;2 keys to get
raklp:	push bc
	push hl
	call dokey
	pop hl
	ld (hl),a	;log newly attained key
	inc hl
	call printkeychoice
	pop bc
	djnz raklp
	call printstring
fdklp:	call any23560	;check for Y/N
	cp 'n'
	push af
	call z,redscreen
	pop af
	jr z,refinekeys
	cp 's'
	jr nz,fdklp
	ld a,68
	call paperfill0
	call delay1
	call cls
	ld a,7
	call paperfill0
	scf	;so introscreen knows something has happened
	ret
	;
redscreen:
	ld a,2
	call paperfill0
	call badbeep
	call delay1
	ret
	;
dokey:
	call nokey
	call printstring	;print "UP" "DOWN" etc
dklp:	call 654		;ROM get key
	ld a,e
	inc a
	jr z,dklp
	ld b,1;4		;check against remaining 4... keys
	ld hl,35339	;key logs
cklp:	ld a,e
	cp (hl)		;check key hasn't already been picked
	push af
	push bc
	push de
	call z,badbeep	;if a repeat we mark it
	pop de
	pop bc
	pop af
	jr z,dklp
	inc hl
	djnz cklp
	ret
	;
printkeychoice:
	push bc
	push de
	push hl
	ld d,0
	ld e,a
	ld hl,keycodetab
	add hl,de
	ld a,(hl)
	ld (charnum),a
	ld hl,textx
	dec (hl)
	dec (hl)
	call bigprint
	call keytapsound
	call delay1
	pop hl
	pop de
	pop bc
	ret
	;
keystring0:	db	246,244,0,245,7,248,69,68,4,5,254,4
		db	253,2,0,'DEFINIR TECLAS'
	db	248,71,7,7,7
keystring:
	db	253,3,9,	"DIREITA:   ",255
	db	253,3,13,	"ESQUERDA:  ",255

	;db	253,8,11,"JUMP :  ",255
	;db	253,8,15,"SWITCH: ",255
	;db	253,8,19,"PAUSE:  ",255
	db	248,70,6,6,6
	db	253,7,22,'OKAY S/N?',255
	;
keycodetab:	;keys from 1 - 39 as returned in low byte of DE from ROM routine 654
	db	'B',	'H',	'Y',	'6',	'5',	'T',	'G',	'V',	'N',	'J'
	db	'U',	'7',	'4',	'R',	'F',	'C',	'M',	'K',	'I',	'8'
	db	'3',	'E',	'D',	'X',	'*',	'L',	'O',	'9',	'2',	'W'	;* is Sym
	db	'S',	'Z',	'_',	'<',	'P',	'0',	'1',	'Q',	'A',	'^'	;underscore is Spc, ^ is caps, < is Ent
	;
topchar:	equ	128
	;
instructions:
	call keytapsound
	call nokey
	ld ix,intstring
	call printstring
	call drawinstrtiles
	ld bc,0	;setting x y for jumping sprout anim
	call sint
instrloop:
	halt
	halt
	ld hl,(ospradd)		;delete tilesprout
	call deletetile
	call dohappysprout
	ld hl,loopcounter
	inc (hl)
	ld a,(hl)
	ld hl,switch0
	and 8
	jr nz,smiss
	ld hl,switch1
smiss:	ld de,3840
	call yx2cell
	call printtile
	call anykeyinloop
	jr z,instrloop
	call crashdrummy
	scf	;so introscreen knows what to do on return
	ret
	;
drawinstrtiles:
	ld de,2048
	call yx2cell
	ld hl,keytile
	call printtile
	ld de,3072
	call yx2cell
	ld hl,present
	call printtile
	ld de,3840
	call yx2cell
	ld hl,switch0
	call printtile
	ret
	;
setupintroscreen:
	ld bc,15480	;120 in C, 60 in B
sint:	ld (sxcor),bc
	xor a
	out (254),a
	ld (sframe),a
	ld (ospradd+1),a
	ld hl,sycortab
	ld (sypos),hl	;reset variables
	ret
	;
printstring:
	ld a,(ix+0)
	inc ix
	cp 255			;end string = 255
	ret z
	cp topchar
	push af
	call nc,controlcode
	pop af
	jr nc,printstring
	ld (charnum),a		;store ASCII to print
	call printit
	jr printstring
	;
getchar:			;arrive A holding ASCII, point HL at graphic
	ld bc,(fontseed)
gethchar:
	ld h,0
	ld l,a
	add hl,hl
	add hl,hl
	add hl,hl		;x8
	add hl,bc
	ret
	;
charnum:		db	0
textx:			db	0
texty:			db	0	
printroutine:		db	5	;0=64,1=normal,2=boldprint,3=tall,4=big,5=vbig,6=giant
papercolour:		db	56
fontcolour:		db	71
tallfontcolour:		db	71,70,70,07	;used by tall, big and very big print routines
giantfontcolour:	db	80
charhalf:		db	11110000b	;char mask for print 64
fontseed:		dw	portuguesefont-256;15360
margin:			db	0
	;
printit:
	ld a,(printroutine)
	add a,a		;byte to word
	ld b,0
	ld c,a
	ld hl,printroutinetab
	add hl,bc
	ld a,(hl)
	inc hl
	ld h,(hl)
	ld l,a
	jp (hl)
	;
printroutinetab:
	dw	halfprint
	dw	normalprint
	dw	boldprint
	dw	tallprint
	dw	bigprint
	dw	verybigprint
	dw	giantprint
	;
halfprint:
	ld a,(charnum)
	cp ' '
	scf
	call z,wordwrap64	;if we're about to start a new word, check it will fit
	ret nc			;nc means we've moved down a row, and we don't want a space starting a line
	ld de,(textx)
	call yx2cell		;point DE at screen
	ld a,(charnum)
	cp 96		;no lower case
	jr c,hpc
	sub 32
hpc:	ld bc,halffont-256
	call gethchar
halfchar:
	ld a,(charhalf)
	ld c,a
	cpl
	ld (charhalf),a
	ld b,8
	bit 7,c
	jr z,hpright
hpleft:				;left hand side of a character cell
	ld a,(hl)		;which we can clear with LD
	and c
	ld (de),a
	inc hl
	inc d
	djnz hpleft
	dec d
	call colourchar
	ret
	;
hpright:
	ex de,hl
hprlp:	ld a,(de)
	and c
	or (hl)
	ld (hl),a
	inc de
	inc h
	djnz hprlp
	call nextcell
	ret
	;
normalprint:
	ld a,(charnum)
	cp ' '
	scf
	call z,wordwrap32	;if we're about to start a new word, check it will fit
	ret nc			;nc means we've moved down a row, and we don't want a space starting a line
	ld de,(textx)
	call yx2cell		;point DE at screen
	ld a,(charnum)
	call getchar		;point HL at graphic in normal font
	call printchar	
	call colourchar
	call nextcell
	ret
	;
wordwrap64:
	ld a,(textx)	;0-31
	add a,a		;0-62
	jr z,missprint	;we don't want to print a space at start of line
	ld e,a
	ld b,64
	call wrap	;every letter
	ret
	;
wordwrap32:
	ld b,32
	ld de,(textx)		;column in E
	ld a,e
	or a			;are we at the start of a row? If so we don't want to start with a space
	jr z,missprint
wrap:	push ix
	pop hl
	jr wwent
stillinword:
	inc e
	inc hl
wwent:	ld a,(hl)
	cp 255
	jr z,outword
	cp ' '
	jr nz,stillinword
outword:
	ld a,e
	cp b		;B =32 or 64
	ret c
	ld hl,textx	;we're going to overspill, so move down a row
	call ncd
missprint:
	and a		;unset carry flag
	ret
	;
boldprint:
	ld a,(charnum)
	cp ' '
	scf
	call z,wordwrap32	;if we're about to start a new word, check it will fit
	ret nc			;nc means we've moved down a row, and we don't want a space starting a line
	ld de,(textx)
	call yx2cell		;point DE at screen
	ld a,(charnum)
	call getchar		;point HL at graphic in normal font
	call printbold
	call colourchar
	call nextcell
	ret
	;
tallprint:
	ld de,(textx)
	call yx2cell		;point DE at screen
	ld a,(charnum)
	call getchar		;point HL at graphic in normal font
	call printtallchar
	ld bc,(textx)
	call yx2attr		;HL at ATTR
	ld bc,32
	ld a,(tallfontcolour)
	ld (hl),a
	add hl,bc
	ld a,(tallfontcolour+1)
	ld (hl),a
nextcelltall:
	ld hl,textx
	inc (hl)		;next column along
	ld a,(hl)
	cp 32
	ret c
	ld a,(margin)
	ld (hl),a		;end reached
	inc hl
	inc (hl)
	inc (hl)
	ld a,(hl)
	cp 24
	ret c
	ld (hl),0
	ret
	;
bigprint:
	ld de,(textx)
	call yx2cell
	ld a,(charnum)
	call getchar
	push de
	call bigchar
	pop de
	call bigcolour
	ld hl,textx
	inc (hl)
	inc (hl)
	ld a,(hl)
	cp 32
	ret c
	ld (hl),0
	inc hl
	inc (hl)
	inc (hl)
	ld a,(hl)
	cp 24
	ret c
	ld (hl),0
	ret
	;
verybigprint:
	ld de,(textx)
	call yx2cell
	ld a,(charnum)
	call getchar
	push de
	call verybigchar
	pop de
	call verybigcolour
	ld hl,textx
	ld a,(hl)
	add a,4
	ld (hl),a
	cp 32
	ret c
	ld (hl),0
	inc hl
	ld a,(hl)
	add a,4
	ld (hl),a
	cp 24
	ret c
	ld (hl),0
	ret
	;
giantprint:
	ld de,(textx)
	call yx2cell
	ld a,(charnum)
	call getchar
	call giantchar
	ld hl,textx
	ld a,(hl)
	add a,8
	ld (hl),a
	cp 32
	ret c
	ld (hl),0
	inc hl
	ld a,(hl)
	add a,8
	ld (hl),a
	cp 24
	ret c
	ld (hl),0
	ret
	;
colourchar:			;DE pointing at screen cell
	call screen2att		;point DE at correct ATTR
	ld a,(fontcolour)
	ld (de),a
	ret
	;
tallcolour:
	call screen2att
	ex de,hl
	ld de,32
	ld a,(tallfontcolour)
	ld (hl),a
	add hl,de
	ld a,(tallfontcolour+1)
	ld (hl),a
	ret
	;
bigcolour:
	call tallcolour
	inc l
	ld (hl),a
	and a
	sbc hl,de
	ld a,(tallfontcolour)
	ld (hl),a
	ret
	;
verybigcolour:
	call screen2att
	ex de,hl
	ld de,32
	ld bc,fontcolour+1
	ld a,4
vcclp:	ex af,af'
	ld a,(bc)
	push hl
	ld (hl),a
	inc l
	ld (hl),a
	inc l
	ld (hl),a
	inc l
	ld (hl),a
	pop hl
	add hl,de
	inc bc
	ex af,af'
	dec a
	jr nz,vcclp
	ret
	;
giantchar:	;hl at graphic, de at screen
	ld a,8
gclp2:	push af
	push de
	ld b,(hl)
	inc hl
	ld a,8
gclp1:	push af
	push de
	rl b
	jr nc,missg
	ld c,8
	ld a,170	;hash pattern
	push de
gclp:	ld (de),a
	inc d
	cpl
	dec c
	jr nz,gclp
	pop de
	call screen2att
	ld a,(giantfontcolour)
	ld (de),a
missg:	pop de
	inc e
	pop af
	dec a
	jr nz,gclp1
	pop de
	call nextrowdown
	pop af
	dec a
	jr nz,gclp2
	ret
	;
nextcell:			;next cell or row along
	ld hl,textx
	inc (hl)		;next column along
	ld a,(hl)
	cp 32
	ret c
ncd:	ld a,240
	ld (charhalf),a		;for half print
	ld a,(margin)
	ld (hl),a		;end reached
	inc hl
	inc (hl)		;one row down
	ld a,(hl)
	cp 24			;off bottom yet?
	ret c
	ld (hl),0		;back to top
	ret	
	;
printchar:			;HL at graphic, DE at screen
	ld b,8
pclp:	ld a,(hl)
	ld (de),a
	inc hl
	inc d
	djnz pclp
	dec d
	ret
	;
printtile:	;hl at graphic, de at screen
	push de
	ld b,16
plp:	ld a,(hl)
	ld (de),a
	inc hl
	inc e
	ld a,(hl)
	ld (de),a
	inc hl
	dec e
	call nextlinedown
	djnz plp
	pop de
	call screen2att
colourtile:	;hl at 4 colours,de at ATTRS
	ldi
	ldi
	ex de,hl
	ld bc,30
	add hl,bc
	ex de,hl
	ldi
	ldi
	ret
	;
printbold:
	ld a,(fontseed+1)	;check if ROM font
	cp 64
	jr nc,prbold	;check if 'm' or 'w' as they don't bold well
	ld a,(charnum)
	cp 'm'
	jr z,printm
	cp 'w'
	jr z,printw
prbold:	ld b,8
pcblp:	ld a,(hl)
	and a
	rra
	or (hl)
	ld (de),a
	inc hl
	inc d
	djnz pcblp
	dec d
	ret
	;
printm:	ld hl,bold_m
	jp printchar
	;
printw:	ld hl,bold_w
	jp printchar

	;
bold_m:	db 0, 0, 116, 106, 106, 106, 106, 0
bold_w:	db 0, 0, 106, 106, 106, 106, 116, 0
	;
	;
printtallchar:
	ld b,8
ptclp:	ld a,(hl)
	ld (de),a
	call nextlinedown
	ld a,(hl)
	ld (de),a
	call nextlinedown
	inc hl
	djnz ptclp
	ret
	;
bigchar:
	ld b,8
lp2:	push bc
	push de
	ld b,(hl)
	ld a,2
lp1:	push af
	ld a,1
lp0:	rl b
	rl a
	rl a
	jr nc,lp0
	and a
	ld c,a
	rra
	or c
	ld (de),a
	inc d
	ld (de),a
	inc e
	dec d
	pop af
	dec a
	jr nz,lp1
	inc hl
	pop de
	inc d
	call nextlinedown
	pop bc
	djnz lp2
	ret
	;
verybigchar:
	ld a,4
vblp1:	push af
	ld b,(hl)
	inc hl
	ld c,(hl)
	inc hl
	push de
	ld a,4
vblp:	push af
	push de
	xor a
	rl b
	jr nc,miss0
	or $F0
miss0:	rl b
	jr nc,miss1
	or $0F
miss1:	call half_char
	xor a
	rl c
	jr nc,miss2
	or $F0
miss2:	rl c
	jr nc,miss3
	or $0F
miss3:	call half_char
	pop de
	inc e
	pop af
	dec a
	jr nz,vblp
	pop de
	call nextrowdown
	pop af
	dec a
	jr nz,vblp1
	ret
	;
half_char
	ld (de),a
	inc d
	ld (de),a
	inc d
	ld (de),a
	inc d
	ld (de),a
	call nextlinedown
	ret
	;
controlcode:
	cpl			;makes table easier
	add a,a
	ld b,0
	ld c,a
	ld hl,controlcodetab
	add hl,bc
	ld a,(hl)
	inc hl
	ld h,(hl)
	ld l,a
	jp (hl)
	;
introstring0:
	db	246	;cls
	db	253,2,0	;print at
	db	249,7	;normal font colour
	db	248,69,68,68,4	;big font colour
	db	254,5		;very big print
	db	244,0		;border
	db	245,68		;paper
	db	'SPROUTY'
	db	254,3
	db	248,71,07,07,07
	db	253,8,16
	db	251,8
	DB	'1 - INICIAR JOGO',252,252
	DB	'2 - INSTRUcoES',252,252
	DB	'3 - DEFINIR TECLAS ',255
	;
intstring:
	db	246	;cls
	db	253,4,0	;print at
	db	254,1
	db	251,4
	db	'O TEU NOME e SPROUTY  E eS UMA COUVE-DE-BRUXELAS. '
	db	'e NATAL E ESTbS TaO ANSIOSO POR ABRIR AS '
	db	'PRENDAS QUE NaO '
	db	253,4,4,'CONSEGUES PARAR DE SALTAR. '
	db	253,4,8	;print at
	DB	'e ENTaO UM JOGO COM APENAS '
	db	253,4,9,'2 TECLAS. QUANDO NaO '
	db	'ESTbS A '
	db	253,4,10,'ANDAR, ESTbS A SALTAR.'
	db	253,4,12	;print at
	DB	'A MISSaO e ALCANcAR AS PRENDAS. TENS QUE EVITAR OS '
	db	'MAUZoES E LIGAR OS INTERRUPTORES PARA ABRIR OS PORToES.'
	db	253,0,19	;print at
	DB	250,'18 NiVEIS. VIDAS INFINITAS. ',252
	db	254,4
	db	248,66,6,68,4	;big font colour
	db	253,5,21	;print at
	DB	'DIVERTE-TE!',255
	;
finstring:
	db	246	;cls
	db	249,7	;normal font colour
	db	248,68,4,68,4	;big font colour
	db	254,4		;big print
	db	244,0		;border
	db	253,7,8
	db	'PARABeNS!'
	db	248,68,4,68,4	;big font colour
	db	253,2,12
	db	'JOGO COMPLETO!'
	db	254,4		;big print
	db	245,248		;paper
	db	242,220		;delay
	db	246		;cls
	db	245,68		;paper
	db	253,8,8
	db	'ALELUIA!'
	db	253,2,11
	db	'CHOVEM COUVES!'
	db	242,220		;delay
	db	255
		;
controlcodetab:
	dw	donowt		;255	end string
	dw	setprintroutine	;254,x
	dw	printat		;253,x,y
	dw	nextrow		;252 moves one row down plus margin
	dw	setmargin	;251,x
	dw	centrestring	;250
	dw	setfontcolour	;249,c
	dw	setbigcolour	;248,c,c,c,c
	dw	setgiantcolour	;247,c
	dw	cls		;246
	dw	paperfill	;245
	dw	border		;244
	dw	waitkey		;243
	dw	stringdelay	;242,#halts
	;
setprintroutine:
	ld a,(ix+0)
	inc ix
	ld (printroutine),a
	ret
	;
printat:
	ld hl,textx
	ld a,(ix+0)
	inc ix
	ld (hl),a
	inc hl
	ld a,(ix+0)
	inc ix
	ld (hl),a
	ret
	;
nextrow:		;equivalent to pressing ENTER
	ld hl,textx
	ld a,(margin)
	ld (hl),a
	inc hl
	inc (hl)
	ld a,(hl)
	cp 24
	ret c
	ld (hl),0
	ret
	;
setmargin:
	ld a,(ix+0)
	inc ix
	ld (margin),a
	ret
	;
centrestring:		;finds length of string & centres
	push ix		;if >31 does nowt
	ld b,0		;count string length in b
cslp:	inc ix	
	inc b
	bit 5,b		;bit 5 set means string too long
	jr nz,csout
	ld a,(ix+0)
	cp topchar		;keep going until the next control code
	jr c,cslp
	ld a,32		;b holds string length 0-31
	sub b
	srl a		;different divided by 2
	ld (textx),a
csout:	pop ix
	ret
	;
setfontcolour:
	ld a,(ix+0)
	inc ix
	ld (fontcolour),a
	ret
	;
setbigcolour:		;same for tall, big, very big
	ld hl,tallfontcolour
	ld b,4
stclp:	ld a,(ix+0)
	inc ix
	ld (hl),a
	inc hl
	djnz stclp
	ret
	;
setgiantcolour:
	ld a,(ix+0)
	inc ix
	ld (giantfontcolour),a
	ret
	;
cls:	ld hl,16384
	ld d,h
	ld e,1
	ld (hl),l
	ld bc,6143
	ldir
	ret
	;
paperfill:
	ld a,(ix+0)
	inc ix
paperfill0:	;fill ATTRS with colour A
	ld hl,22528
	ld d,h
	ld e,1
	ld bc,767
	ld (hl),a
	ldir
	ret
	;
border:
	ld a,(ix+0)
	inc ix
	out (254),a
	ret
	;
waitkey:
	call nokey
anykey:	xor a
	in a,(254)
	cpl
	and 31
	jr z,anykey
	ret
	;
any23560:
	call nokey
	ld hl,23560
	ld (hl),0
a2klp:	ld a,(hl)
	or a
	jr z,a2klp
	ret
	;
	;
anykeyinloop:	;checks all keys, for the purposes of being called once per loop
	xor a
	in a,(254)
	cpl
	and 31
	ret
	;
nokey:	xor a
	in a,(254)
	cpl
	and 31
	jr nz,nokey
	ret
	;
nextlinedown:		;move DE down a pixel line
	inc d
	ld a,d
	and 7
	ret nz
	ld a,e
	add a,32
	ld e,a
	ret c
	ld a,d
	sub 8
	ld d,a
	ret
	;
nextrowdown:		;move DE down one line
	ld a,e
	add a,32
	ld e,a
	ret nc
	ld a,d
	add a,8
	ld d,a
	ret
	;
screen2att:
	ld a,d
	rra
	rra
	rra
	and 3
	or 88
	ld d,a	
	ret
	;
yx2attr:	;arrive b=y c=x, point HL at ATTRS
	ld h,0
	ld l,b
	add hl,hl
	add hl,hl
	add hl,hl
	add hl,hl
	add hl,hl	;x32
	ld a,l
	or c
	ld l,a
	ld a,h
	or 88
	ld h,a
	ret
	;
yx2cell:	;arrive with d=y, e=x
	ld a,d
	rrca
	rrca
	rrca
	and 224
	or e
	ld e,a
	ld a,d
	and 24
	or 64
	ld d,a
	ret
	;
yx2pix:		;arrive with B=y 0-192, C=x 0-255, return with DE at corresponding screen
	ld a,b
	rra
	rra
	rra
	and 24
	or 64
	ld d,a
	ld a,b
	and 7
	or d
	ld d,a
	ld a,b
	rla
	rla
	and 224
	ld e,a
	ld a,c
	rra
	rra
	rra
	and 31
	or e
	ld e,a
	ret
	;
halffont:
	;
;
portuguesefont:
; ASM data file from a ZX-Paintbrush picture with 256 x 24 pixels (= 32 x 3 characters)

; block based output of pixel data - each block contains 8 x 8 pixels

; blocks at pixel positionn (y=0):

db 0, 0, 0, 0, 0, 0, 0, 0
db 0, 60, 60, 60, 60, 0, 60, 0
db 0, 108, 108, 108, 0, 0, 0, 0
db 0, 44, 126, 44, 44, 126, 44, 0
db 40, 40, 255, 168, 255, 41, 255, 40
db 0, 98, 100, 8, 16, 38, 70, 0
db 0, 48, 104, 48, 106, 236, 122, 0
db 0, 12, 12, 16, 0, 0, 0, 0
db 0, 24, 48, 48, 48, 48, 24, 0
db 0, 24, 12, 12, 12, 12, 24, 0
db 0, 0, 90, 60, 60, 90, 0, 0
db 0, 24, 24, 126, 126, 24, 24, 0
db 0, 0, 0, 0, 0, 24, 24, 32
db 0, 0, 0, 126, 126, 0, 0, 0
db 0, 0, 0, 0, 0, 24, 24, 0
db 0, 2, 4, 8, 16, 32, 64, 0
db 0, 254, 246, 246, 246, 246, 246, 254
db 0, 60, 28, 28, 28, 28, 28, 28
db 0, 126, 70, 6, 126, 96, 96, 126
db 0, 126, 6, 30, 6, 6, 126, 126
db 0, 96, 96, 96, 108, 126, 12, 12
db 0, 126, 96, 126, 6, 6, 126, 126
db 0, 96, 96, 96, 126, 114, 114, 126
db 0, 126, 6, 6, 30, 24, 24, 24
db 0, 126, 114, 126, 114, 114, 114, 126
db 0, 126, 70, 70, 126, 6, 6, 6
db 0, 0, 0, 24, 0, 24, 0, 0
db 0, 0, 0, 24, 0, 24, 24, 48
db 0, 0, 12, 24, 48, 24, 12, 0
db 0, 0, 0, 126, 0, 126, 0, 0
db 0, 0, 48, 24, 12, 24, 48, 0
db 0, 126, 70, 6, 30, 0, 24, 0

; blocks at pixel positionn (y=8):

db 0, 24, 0, 120, 96, 98, 126, 0
db 0, 254, 158, 254, 158, 158, 158, 0
db 0, 248, 152, 254, 254, 158, 254, 0
db 0, 248, 152, 128, 128, 142, 254, 0
db 0, 252, 246, 242, 242, 246, 252, 0
db 0, 252, 192, 240, 192, 254, 254, 0
db 0, 254, 192, 248, 224, 224, 224, 0
db 0, 248, 184, 128, 190, 158, 254, 0
db 0, 226, 226, 226, 254, 226, 226, 0
db 0, 60, 0, 60, 60, 60, 60, 0
db 0, 254, 14, 14, 14, 142, 254, 0
db 0, 246, 246, 252, 246, 246, 246, 0
db 0, 240, 240, 240, 240, 240, 254, 0
db 0, 254, 234, 234, 234, 226, 226, 0
db 0, 252, 246, 246, 246, 246, 246, 0
db 0, 254, 246, 246, 246, 246, 254, 0
db 0, 254, 242, 242, 254, 240, 240, 0
db 0, 252, 196, 204, 222, 254, 12, 0
db 0, 252, 228, 228, 248, 246, 246, 0
db 0, 126, 192, 124, 14, 14, 252, 0
db 0, 254, 56, 56, 56, 56, 56, 0
db 0, 242, 242, 242, 242, 242, 254, 0
db 0, 242, 242, 242, 242, 116, 56, 0
db 0, 226, 226, 226, 234, 234, 254, 0
db 0, 226, 226, 226, 60, 226, 226, 0
db 0, 242, 242, 242, 254, 56, 56, 0
db 0, 254, 30, 60, 120, 240, 254, 0
db 0, 30, 24, 24, 24, 24, 30, 0
db 0, 64, 96, 48, 24, 12, 4, 0
db 0, 120, 24, 24, 24, 24, 120, 0
db 0, 24, 60, 126, 24, 24, 24, 0
db 0, 0, 0, 0, 0, 0, 0, 255

; blocks at pixel positionn (y=16):

db 170, 85, 170, 85, 170, 85, 170, 85
db 20, 40, 254, 158, 254, 158, 158, 158
db 56, 0, 254, 158, 254, 158, 158, 158
db 0, 252, 204, 192, 206, 254, 48, 96
db 0, 6, 6, 6, 126, 70, 126, 0
db 56, 0, 252, 192, 240, 192, 254, 254
db 0, 28, 48, 48, 56, 48, 48, 0
db 0, 0, 126, 70, 70, 126, 6, 126
db 0, 96, 96, 126, 98, 98, 98, 0
db 28, 112, 0, 124, 124, 124, 124, 124
db 0, 12, 0, 12, 12, 44, 60, 0
db 0, 96, 100, 124, 120, 108, 102, 0
db 0, 0, 24, 24, 24, 24, 28, 0
db 0, 0, 126, 106, 106, 98, 98, 0
db 0, 0, 126, 98, 98, 98, 98, 0
db 20, 40, 254, 246, 246, 246, 246, 254
db 0, 0, 126, 98, 126, 96, 96, 0
db 0, 0, 126, 70, 126, 6, 7, 7
db 0, 0, 126, 96, 96, 96, 96, 0
db 0, 0, 126, 96, 126, 6, 126, 0
db 0, 24, 60, 24, 24, 24, 28, 0
db 56, 0, 242, 242, 242, 242, 242, 254
db 0, 0, 98, 98, 98, 52, 24, 0
db 0, 0, 98, 106, 106, 106, 126, 0
db 0, 0, 198, 108, 56, 108, 198, 0
db 0, 0, 0, 38, 38, 62, 6, 62
db 0, 0, 126, 14, 60, 112, 126, 0
db 56, 0, 254, 246, 246, 246, 246, 254
db 56, 0, 254, 158, 254, 158, 158, 158
db 0, 60, 0, 60, 60, 60, 60, 0
db 60, 123, 252, 255, 255, 127, 127, 29
db 120, 188, 126, 252, 250, 244, 168, 80
;
numsprout:		equ	17
length_of_sprouttab:	equ	(endsprouttab0-sprouttab0)/numsprout
fastprob:		equ	224
finscreen:
	call nokey
	call longtwistyzap
	call crashdrummy
	ld ix,finstring
	call printstring
	call cls
	ld hl,(23672)
	ld (rsd0+1),hl
	ld a,(23560)
	ld (rsd1+1),a	;set up rnd seeds
	call setupsprouttab
	call setupscreen
congratsmain:	halt
	call delay
	call deletesprout
	ld hl,(ospradd)		;delete tilesprout
	call deletetile
	call drawsprout
	call dohappysprout
	call movesprout
	ld hl,loopcounter
	inc (hl)
	jr congratsmain
	;
loopcounter:	db	0
	;
dohappysprout:	;draw and move sprite
	ld hl,(sypos)
	ld a,(hl)	;get ycor
	ld hl,sdisp
	add a,(hl)
	ld bc,(sxcor)
	ld b,a
	call yx2pix	;DE at screen
	ld (ospradd),de	;for deletion
	push de
	call masktile
	pop de
	ld a,(sframe)
	add a,a
	add a,a
	add a,a
	add a,a
	add a,a	;x32
	ld l,a
	ld h,0
	ld bc,happysproutjump
	add hl,bc	;get correct graphic
	call ortile
	call nextframe
	call nextpos
	ret
	;
nextpos:
	ld hl,(sypos)
	inc hl
	ld (sypos),hl
	ld a,(hl)
	cp 161
	ret c
	ld hl,sycortab
	ld (sypos),hl
	ret
	;
nextframe:
	ld a,(loopcounter)
	rra
	ret c
	ld a,(sframe)
	inc a
	ld (sframe),a
	cp 6
	ret c
	xor a
	ld (sframe),a
	ret
	;
sframe:		db	0	;0 to 5
sypos:		dw	sycortab
sxcor:		db	0
sdisp:		db	126	;we print in different places depending on whether intro or congrats screen
sycortab:	db	34,26,20,16,12,10,8,6,4,3,2,1,0,0,0,1,2,3,4,6,8,12,16,20,26,255
ospradd:	dw	0
	;
delay:	ld bc,1750
dlp:	dec bc
	ld a,b
	or c
	jr nz,dlp
	ret
	;
stringdelay:
	ld b,(ix+0)
	inc ix
	jr dlp1
	;
delay1:	ld b,10
dlp1:	halt
	djnz dlp1
	ret
	;
	;
setupscreen:
	xor a
	out (254),a
	ld (ospradd+1),a
	ld (sframe),a
	ld hl,sycortab
	ld (sypos),hl	;reset variables
	ld a,120
	ld (sxcor),a
	ld a,126
	ld (sdisp),a
	ld a,68		;green
	call paperfill0
	ld de,22528+32
	ld hl,wootATTR
	ld bc,256
	ldir
	ld hl,23232
sclp:	ld (hl),127
	inc l
	jr nz,sclp
	ret
	;
setupsprouttab:
	ld ix,sprouttab0
	ld b,numsprout
suslp:	push bc
	call rnd
	and 248
	ld (ix+0),a	;xcor
	call rnd
	and 127
	ld c,a
	call rnd
	and 31
	add a,c
	ld (ix+1),a	;ycor
	call rnd
	cp fastprob
	ld (ix+2),4	;rare high speed
	jr nc,sst
	and 1
	inc a		;1 or 2
	ld (ix+2),a	;speed 1 or 2
sst:	ld (ix+3),0
	ld (ix+4),0	;deletescadds
	pop bc
	ld de,length_of_sprouttab
	add ix,de
	djnz suslp
	ret
	;
deletesprout:
	ld ix,sprouttab0
	ld b,numsprout
dslp0:	push bc
	ld h,(ix+4)
	ld l,(ix+3)
	ld c,0
	ld b,8
dslp:	ld (hl),c
	call nexthldown
	djnz dslp
	pop bc
	ld de,length_of_sprouttab
	add ix,de
	djnz dslp0
	ret
	;
drawsprout:
	ld ix,sprouttab0
	ld b,numsprout
drlp0:	push bc
	ld b,(ix+1)
	ld c,(ix+0)
	call yx2pix	;point DE at screen
	ld (ix+4),d	;save for deletion
	ld (ix+3),e
	ld a,(ix+5)	;char#
	add a,a
	add a,a
	add a,a
	ld hl,charsprout
	ld c,a
	ld b,0
	add hl,bc
	call printchar_anyline
	pop bc
	ld de,length_of_sprouttab
	add ix,de
	djnz drlp0
	ret
	;
movesprout:
	ld ix,sprouttab0
	ld b,numsprout
mvlp0:	push bc
	ld a,(ix+1)	;ycor
	add a,(ix+2)	;vdisp
	ld (ix+1),a
	cp 167
	call nc,generatesprout0	;off bottom? make new sprout if yes
	pop bc
	ld de,length_of_sprouttab
	add ix,de
	djnz mvlp0
	ret
	;
generatesprout0:	;small sprout
	inc (ix+5)
	ld a,(ix+5)
	cp 5		;we cycle through frames 0-4 of exploding sprout before resetting
	ret c
	ld (ix+5),0
	call rnd
	and 248
	ld (ix+0),a	;xcor
	ld (ix+1),0	;ycor (new at top)
	call rnd
	cp fastprob
	ld (ix+2),4
	ret nc
	and 1
	inc a
	ld (ix+2),a	;speed 1,2, or 4
	ret
	;
dotilesprout:
	call rnd
	and 31
	cp 31
	jr z,dotilesprout
	ld d,64
	ld e,a
	ld hl,tilesprout
	call ortile
	ret
	;
sprouttab0:	
rept	numsprout
		db	0,0,1	;x y cor, v disp
		dw	0	;oscadd
		db	0	;char#
endrep
endsprouttab0:
	;
printchar_anyline:	;printchar, not line restricted
rept	7
	ld a,(hl)
	ld (de),a
	inc hl
	call nextlinedown
endrep
	ld a,(hl)
	ld (de),a
	ret
	;
deletetile:	;arrive HL at screen
	ld c,0
	ld b,16
dtlp:	ld (hl),c
	inc l
	ld (hl),c
	dec l
	call nexthldown
	djnz dtlp
	ret
	;
ortile:
	ld b,16
ptlp:	ld a,(de)
	or (hl)
	ld (de),a
	inc hl
	inc e
	ld a,(de)
	or (hl)
	ld (de),a
	inc hl
	dec e
	call nextlinedown
	djnz ptlp
	ret
	;
masktile:	;arrive de at screen
	ld hl,mask
	ld b,16
mtlp:	ld a,(de)
	and (hl)
	ld (de),a
	inc hl
	inc e
	ld a,(de)
	and (hl)
	ld (de),a
	inc hl
	dec e
	call nextlinedown
	djnz mtlp
	ret
	;
nexthldown:
	inc h
	ld a,h
	and 7
	ret nz
	ld a,l
	add a,32
	ld l,a
	ret c
	ld a,h
	sub 8
	ld h,a
	ret
	;
;PATRIK RAK's XOR SHIFT RND generator
rnd:
	push hl
	push de
rsd0:	ld  hl,0xA280   ; yw -> zt
rsd1:	ld  de,0xC0DE   ; xz -> yw
	ld  (rnd+6),hl  ; x = y, z = w
	ld  a,l         ; w = w ^ ( w << 3 )
	add a,a
	add a,a
	add a,a
	xor l
	ld  l,a
	ld  a,d         ; t = x ^ (x << 1)
	add a,a
	xor d
	ld  h,a
	rra             ; t = t ^ (t >> 1) ^ w
	xor h
	xor l
	ld  h,e         ; y = z
	ld  l,a         ; w = t
	ld  (rnd+3),hl
	pop de
	pop hl
	ret
	;
tilesprout:
db 13, 180
db 61, 118
db 94, 238
db 110, 223
db 245, 188
db 123, 187
db 187, 181
db 91, 182
db 237, 175
db 245, 222
db 117, 220
db 123, 218
db 29, 52
db 18, 204
db 13, 112
db 6, 192
;
mask:
defb 248, 31
defb 224, 7
defb 192, 3
defb 128, 1
defb 128, 1
defb 0, 0
defb 0, 0
defb 0, 0
defb 0, 0
defb 0, 0
defb 0, 0
defb 128, 1
defb 128, 1
defb 192, 3
defb 224, 7
defb 248, 31
;
keytile:
db 254, 254, 142, 142, 174, 174, 174, 142, 142, 190, 254, 254, 254, 254, 0, 0
db 0, 0, 24, 48, 36, 72, 36, 72, 60, 120, 60, 120, 60, 120, 60, 120
db	7,7,6,6
present:
db 254, 127, 254, 127, 0, 0, 0, 0, 254, 127, 254, 127, 254, 127, 254, 127
db 0, 0, 126, 170, 127, 212, 127, 250, 127, 254, 127, 254, 0, 0, 0, 0
db	113,113,1,1
switch0:
db 0, 0, 0, 6, 0, 54, 0, 118, 0, 246, 0, 246, 0, 246, 30, 246
db 126, 246, 254, 246, 248, 118, 240, 182, 96, 70, 0, 48, 0, 6, 0, 0
db	5,5,5,5
switch1:
db 0, 0, 0, 6, 0, 54, 96, 118, 240, 246, 248, 246, 254, 246, 126, 246
db 30, 246, 0, 246, 0, 118, 0, 182, 0, 70, 0, 48, 0, 6, 0, 0
db	5,5,5,5
;
charsprout:
db 94, 237, 107, 171, 173, 221, 106, 52
db 0, 0, 60, 94, 92, 106, 247, 239	;4 frames of exploding sprout
db 0, 0, 17, 64, 1, 153, 191, 255
db 128, 1, 132, 144, 4, 209, 183, 124
db 34, 0, 129, 32, 4, 0, 32, 8
;
happysproutjump:
; ASM data file from a ZX-Paintbrush picture with 16 x 96 pixels (= 2 x 12 characters)

; line based output of pixel data:

db 0, 0, 0, 0, 3, 192, 15, 240, 31, 248, 59, 220, 53, 172, 113, 142
db 123, 222, 127, 254, 123, 222, 60, 60, 28, 248, 7, 224, 0, 0, 14, 112
db 0, 0, 0, 0, 7, 240, 27, 216, 53, 172, 49, 140, 123, 222, 127, 254
db 119, 238, 120, 30, 124, 254, 51, 204, 45, 180, 13, 176, 4, 32, 0, 0
db 0, 0, 0, 0, 7, 224, 31, 248, 63, 252, 57, 204, 118, 182, 118, 182
db 117, 214, 121, 206, 127, 254, 63, 252, 31, 248, 7, 240, 0, 0, 0, 0
db 14, 112, 0, 0, 7, 224, 31, 248, 63, 252, 127, 254, 127, 254, 127, 254
db 127, 254, 63, 252, 63, 252, 31, 248, 15, 240, 3, 192, 0, 0, 0, 0
db 0, 0, 0, 0, 23, 232, 47, 244, 31, 248, 63, 252, 127, 254, 127, 254
db 127, 254, 123, 222, 113, 142, 53, 172, 27, 216, 15, 240, 0, 0, 0, 0
db 0, 0, 0, 0, 7, 224, 31, 248, 63, 252, 63, 252, 123, 222, 117, 174
db 113, 142, 123, 222, 127, 254, 59, 220, 28, 56, 7, 240, 0, 0, 0, 0
;
wootATTR:
db 68, 68, 68, 68, 9, 9, 9, 9, 9, 9, 9, 9, 68, 68, 68, 68, 9, 9, 9, 9, 9, 9, 9, 9
db 9, 9, 9, 9, 68, 68, 68, 68, 68, 68, 68, 68, 9, 18, 82, 9, 82, 9, 91, 9, 9, 9, 9
db 9, 9, 18, 18, 82, 82, 82, 82, 82, 82, 82, 91, 9, 68, 68, 68, 68, 68, 68, 68, 68
db 9, 18, 82, 9, 82, 9, 82, 9, 18, 82, 82, 91, 9, 9, 9, 9, 9, 9, 18, 82, 9, 9, 9
db 9, 68, 68, 68, 68, 68, 68, 68, 68, 9, 18, 82, 9, 82, 9, 82, 9, 18, 82, 9, 82, 9
db 18, 82, 82, 82, 9, 18, 82, 9, 18, 82, 9, 68, 68, 68, 68, 68, 68, 68, 68, 9, 18
db 82, 82, 82, 82, 82, 9, 18, 82, 82, 82, 9, 18, 82, 9, 82, 9, 18, 82, 9, 9, 9, 9
db 68, 68, 68, 68, 68, 68, 68, 68, 9, 18, 18, 18, 18, 18, 18, 9, 18, 82, 82, 82, 9
db 18, 18, 18, 18, 9, 18, 82, 9, 18, 82, 9, 68, 68, 68, 68, 68, 68, 68, 68, 9, 9
db 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 68, 68, 68
db 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 9, 9, 9, 9, 9, 9, 68, 68, 68, 68
db 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68
;
; line based output of attribute data:
falhaATTR:
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 36, 100, 100, 109, 0, 100, 100, 109, 0, 36, 109, 0, 36, 100, 100, 0, 100, 109, 0, 36, 100, 100, 100, 109, 0
db 0, 36, 100, 100, 100, 0, 100, 0, 100, 0, 36, 100, 0, 36, 100, 100, 0, 100, 100, 0, 36, 100, 0, 0, 100, 0
db 0, 36, 100, 0, 0, 0, 100, 0, 100, 0, 36, 100, 0, 36, 100, 100, 100, 100, 100, 0, 36, 100, 0, 0, 100, 0
db 0, 36, 100, 100, 0, 36, 100, 100, 100, 0, 36, 100, 0, 0, 0, 100, 0, 100, 100, 0, 36, 100, 100, 100, 100, 0
db 0, 36, 100, 0, 0, 36, 100, 0, 100, 0, 36, 100, 100, 100, 0, 100, 0, 100, 100, 0, 36, 100, 0, 0, 100, 0
db 0, 36, 36, 0, 0, 36, 36, 0, 36, 0, 36, 36, 36, 36, 0, 36, 0, 36, 36, 0, 36, 36, 0, 0, 36, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
;
;SOUNDS FOLLOW
;
longtwistyzap:
	ld h,0
tzlp:	call twistyzap
	dec h
	ld a,h
	cp 20
	jr nc,tzlp
	ret
	;
twistyzap:
	ld d,248
	ld e,h
	ld b,20
tzlp0:	ld a,d
	and 248
	out (254),a
	cpl
	ld d,a
	ld c,e
tzlp1:	dec c
	jr nz,tzlp1
	dec e
	djnz tzlp0
	ret
	;
crashdrummy:
                ld hl,16383
	ld de,20
	ld bc,100
blp0:      ld a,(hl)
                dec hl
                and 24
                out (254),a
                push de
blp1:      dec de
                ld a,d
                or e
                jr nz,blp1
                pop de
                ld a,e
                add a,10
                ld e,a
                jr nc,miss
                inc d
miss:      dec bc
                ld a,b
                or c
                jr nz,blp0
                ret
	;
keytapsound:
	ld bc,2000
	ld hl,16383
ktlp:	ld a,(hl)
	and 24
	out (254),a
	dec hl
	dec bc
	ld a,b
	or c
	jr nz,ktlp
	ret
	;
badbeep:	;low note to mark annoyance
	ld e,30
bbdlp0:	ld a,d
	and 24
	out (254),a
	cpl
	ld d,a
	ld bc,1800
bbdlp:	dec bc
	ld a,b
	or c
	jr nz,bbdlp
	dec e
	jr nz,bbdlp0
	ret
	;
