;**********************************************************************;
;*                 A T O M I C   T R I P P L E S                      *;
;*--------------------------------------------------------------------*;
;*    doel           : Spel				              *;
;*--------------------------------------------------------------------*;
;*    filenaam       : TRIPLES.ASM                                    *;
;*    versie         : 1.0 - 991029002                                *;
;*    auteur         : Roland Leurs                                   *;
;*                     The Atomic Development Studio                  *;
;*    ontwikkeld     : oktober 1999                                   *;
;*    laatste update : -                                              *;
;*--------------------------------------------------------------------*;
;*    assembleren    : x6502 triples                                  *;
;*--------------------------------------------------------------------*;
;*    oproep         : LINK #2902                                     *;
;**********************************************************************;

;**********************************************************************;
; Definitie van constanten
;**********************************************************************;
oswrch		equ	$FFF4
oszend		equ	$FFC8
oslees		equ	$FFC5
osbyte		equ	$FFC2
wait		equ	$FE66

decimaal	equ	$45
zp		equ	$70

timer		equ	$6F
minlengte	equ	$7C
maxkleur	equ	$7D
maxdoel		equ	$7E
maxtijd		equ	$7F

score		equ	$80
level		equ	$84
time		equ	$88
goal1		equ	$90
goal2		equ	$94
goal3		equ	$98
goal4		equ	$9C

rij		equ	$2800
veld		equ	$2810

maskgoal1	equ	$80
maskgoal2	equ	$40
maskgoal3	equ	$20
maskgoal4	equ	$10

;**********************************************************************;
; Header voor Atom in PC-formaat
;**********************************************************************;
                org     $28F0
                .dw     program, tripples,0,0,0,0,0,0



program         .db	$0D,$FF

;**********************************************************************
; Hoofdprogramma - Teken het speelveld
;**********************************************************************
tripples	jsr 	zetsem		; zet semafoor
		ldx	#t3e-t3b	; laadt aantal te zenden bytes
		jsr	pccom		; laadt het RAM font uit huidige directory
t3b		.db	$00,$06
		.db	"triples.fnt"
		.db	0
t3e		nop			; einde commando
		jsr	oslees		; lees status
		beq	bouwscherm	; spring indien font geladen

		ldx	#t4e-t4b	; laadt aantal te zenden bytes
		jsr	pccom		; laadt het RAM font vanuit \atom\font
t4b		.db	$00,$06
		.db	"\atom\font\triples.fnt"
		.db	0
t4e		nop			; einde commando
		jsr	oslees		; lees status
		beq	bouwscherm	; spring indien font geladen
		ldx	#msg1e-msg1b	; laadt aantal af te drukken tekens
		jsr	pccom		; print string
msg1b		.db	"TRIPLES.FNT kan niet geladen worden"
		.db 	13,10
msg1e		jmp	exit		; einde programma

bouwscherm	ldx 	#t1e-t1b	; laadt aantal te zenden bytes
		jsr	pccom		; teken speelveld
t1b		.db	22,12		; zet VGA 640*480 DVA-16 mode
		.db	28,0,29,79,0	; text window op 0,29,79,0
		.db	19,8,84		; kleur 8 wordt oranje
		.db	19,7,50		; over lelijk gesproken...
		.db	19,3,1		; kleur 3 wordt rood
		.db	19,4,67		; kleur 4 lijkt op geel
                .db     19,14,88        ; kleur 14 wijzigen in okergeel
                .db     17,14           ; kleur okergeel
		.db	0,$5A,$03	; teken speelveld
		.db	0,0,<479,>479	;   linksonder = 0,479
		.db	<639,>639,0,0	;   rechtsboven = 639,0
                .db     17,0            ; kleur zwart
		.db	0,$5A,$03	; teken kolom 1
		.db	20,0,153,1	;   linksonder = 20,409
		.db	52,0,71,0	;   rechtsboven = 52,71
		.db	0,$5A,$03	; teken kolom 2
		.db	56,0,153,1	;   linksonder = 56,409
		.db	88,0,71,0	;   rechtsboven = 88,71
		.db	0,$5A,$03	; teken kolom 3
		.db	92,0,153,1	;   linksonder = 92,409
		.db	124,0,71,0	;   rechtsboven = 124,71
		.db	0,$5A,$03	; teken kolom 4
		.db	128,0,153,1	;   linksonder = 128,409
		.db	160,0,71,0	;   rechtsboven = 160,71
		.db	0,$5A,$03	; teken kolom 5
		.db	164,0,153,1	;   linksonder = 164,409
		.db	196,0,71,0	;   rechtsboven = 196,71
		.db	0,$5A,$03	; teken kolom 6
		.db	200,0,153,1	;   linksonder = 200,409
		.db	232,0,71,0	;   rechtsboven = 232,71
		.db	0,$5A,$03	; teken kolom 7
		.db	236,0,153,1	;   linksonder = 236,409
                .db     12,1,71,0       ;   rechtsboven = 268,71
		.db	0,$5A,$03	; teken kolom 8
                .db     16,1,153,1      ;   linksonder = 272,409
                .db     48,1,71,0       ;   rechtsboven = 304,71
		.db	0,$5A,$03	; teken kolom 9
                .db     52,1,153,1      ;   linksonder = 308,409
                .db     84,1,71,0       ;   rechtsboven = 340,71
		.db	0,$5A,$03	; teken kolom 10
                .db     88,1,153,1      ;   linksonder = 344,409
                .db     120,1,71,0      ;   rechtsboven = 376,71
t1e		nop			; einde speelveld tabel 

		ldx 	#t2e-t2b	; laadt aantal te zenden bytes
		jsr 	pccom		; teken displays
t2b		.db	0,$5A,$03	; teken score display
		.db	144,1,131,0	;   linksonder = 400,131
		.db	107,2,71,0	;   rechtsboven = 619,71
		.db	0,$5A,$03	; teken level display
		.db	144,1,233,0	;   linksonder = 400,233
		.db	244,1,173,0	;   rechtsboven = 500,173
		.db	0,$5A,$03	; teken time display
		.db	8,2,233,0	;   linksonder = 520,233
		.db	107,2,173,0	;   rechtsboven = 619,173
		.db	0,$5A,$03	; teken goals display
		.db	144,1,153,1	;   linksonder = 400,409
		.db	107,2,19,1	;   rechtsboven = 619,275
		.db	0,$5A,$03	; teken message display
		.db	20,0,205,1	;   linksonder = 20,461
		.db	107,2,173,1	;   rechtsboven = 619,429
t2e		nop			; einde display tabel

		ldx	#t5e-t5b	; laadt aantal bytes
		jsr	pccom		; druk vaste teksten af
t5b		.db	$00,$08,3,2	; tsize 3,2
		.db	$00,$07		; print titel string schaduw
		.db	160,1,21,0	;   op 414,21
		.db	"TRIPLES",0
		.db	17,15		; kleur wit
		.db	$00,$07		; print titel string voorgrond
		.db	157,1,18,0	;   op 411,18
		.db	"TRIPLES",0
		.db	$00,$08,1,1	; tsize 1,1 (normale tekst)
		.db	$00,$07		; print score string
		.db	160,1,75,0	;   op 416,75
		.db	"score",0
		.db	$00,$07		; print level string
		.db	152,1,177,0	;   op 408,177
		.db	"level",0
		.db	$00,$07		; print time string
		.db	16,2,177,0	;   op 528,177
		.db	"time",0
		.db 	$00,$07		; pring goals string
		.db	152,1,23,1	;   op 408,279
		.db	"goal",0
		.db	$00,$08,2,2	; tsize 2,2
		.db	17,2		; kleur donker groen
		.db	$00,$07		; print goal -
		.db	191,1,15,1	;   op 447,287
		.db	"-",0
		.db	$00,$07		; print goal |
		.db	45,2,15,1	;   op 557,287
		.db	"|",0
		.db	$00,$07		; print goal /
		.db	191,1,82,1	;   op 447,338
		.db	"/",0
		.db	$00,$07		; print goal \
		.db	45,2,82,1	;   op 557,338
		.db	"\",0
t5e		nop			; einde teksten
		jsr	wissem		; wis semafoor

		jsr	scroll		; laat inleidende tekst over het scherm lopen
		.db	"Triples *** by Roland Leurs *** Press 'S' to start the game *** "
		.db	"Keys: arrow left: move the top row left, arrow right: move the top "
		.db	"row right, arrow down: drop top row down, esc: quit the game *** "
		.db	$EA

;**********************************************************************
; Hoofdprogramma - Initialiseer het spel
;**********************************************************************
init		lda	#0		; laadt accu
		ldx	#9		; laadt kolom teller
init1		ldy	#10		; laadt rij teller
init2		jsr	zetveld		; reset veldcode
		jsr	steen		; maak cel op het scherm leeg
		dey			; verlaag rij teller
		bpl	init2		; spring indien nog rijen volgen
		dex			; verlaag kolom teller
		bpl	init1		; verlaag indien nog niet alles gedaan
		ldx	#31		; laadt teller
init3		sta	score,x		; reset score, level, tijd en goals
		dex			; verlaag teller
		bpl	init3		; verlaag indien nog niet alles gedaan
		lda	#90		; laadt toegestane tijdsduur
level_a		sta	maxtijd		; zet in werkruimte
		lda	#3		; laadt aantal blokken op rij
level_b		sta 	minlengte	; zet in werkruimte
		lda	#3		; laadt aantal kleuren
level_c		sta	maxkleur	; zet in werkruimte
		lda	#0		; laadt eerste doel
level_d		sta	maxdoel		; zet in werkruimte
		jsr	zetdoelen	; zet de doelen in werkruimte

;**********************************************************************
; Hoofdprogramma - Begin het spel
;**********************************************************************
speel		lda	maxtijd		; laadt maximale tijd
		sta	time		; zet in timer
		lda	#17		; zet kleur 0
		jsr	oszend
		lda	#0
		jsr	oszend
		jsr	timeoutwarning	; wis eventuele tijd-waarschuwing
		inc	level		; verhoog het level
		bne	speel0		; spring indien geen overflow
		inc	level+1		; anders ook hoge byte bijwerken
speel0		jsr	printscore	; werk score display bij
		jsr	printgoal1	; werk goal displays bij
		jsr	printgoal2
		jsr	printgoal3
		jsr	printgoal4
		jsr	printlevel	; werk level display bij
		jsr	printtijd	; werk tijd display bij
		lda	#18		; laadt initiele timerwaarde
		sta	timer		; zet timer
		ldy	#10		; zet y coordinaat
		ldx	#0		; laadt veldteller
speel1		lda	rij,x		; lees speelveld
		bne 	speel2		; spring indien niet leeg
		lda	maxkleur	; lees aantal speelkleuren
		jsr	random		; verzin random kleurcode
		sta	rij,x		; zet in speelrij
		jsr	steen		; kleur veld op het scherm
speel2		inx			; verhoog teller
		cpx	#10		; alle velden gehad?
		bne	speel1		; nee, dan volgende veld

;**********************************************************************
; Hoofdprogramma - timer & lees toetsen, schuif links en rechts
;**********************************************************************
speel3		lda	goal1		; laadt aantal doelen - te gaan
		ora	goal2		; or met aantal doelen |
		ora	goal3		; or met aantal doelen /
		ora	goal4		; or met aantal doelen \
		bne	leestoets	; spring indien nog niet alle doelen gescoord
speel3eneenhalf	lda	#2		; tel dit dubbel bij de score
		jsr	verhoogscore	; en zet dit op het scherm
		jsr 	printtijd	; print resterende tijd
		dec	time		; verlaag tijd
		bne	speel3eneenhalf	; spring indien nog seconden over
		inc	maxdoel		; verhoog doel-pointer
		lda	maxdoel		; lees doel-pointer
		cmp	#5		; laatste doel bereikt?
		bne	level_d		; nee, dan door voor volgende ronde
		inc	maxkleur	; verhoog aantal kleuren
		lda	maxkleur	; laadt nieuw aantal kleuren
		cmp	#14		; hoogste kleur bereikt?
		bne	level_c		; nee, dan door naar volgende ronde
		inc 	minlengte	; verhoog minimum lengte
		lda	minlengte	; laadt minimum lengte
		cmp	#11		; maximale lengte bereikt?
		beq	speel3driekwart	; ja, dan maximale tijd verlagen
		jmp	level_b		; nee, dan door naar volgende ronde
speel3driekwart	lda	#60		; laadt de maximale tijd
		cmp	maxtijd		; staat die op 60?
		bne	speel4		; nee, ga dan verder met het spel
		jmp	kampioen	; zo ja, dan is het spel ten einde
speel4		sta	maxtijd		; nee, dan gaan we aan de tweede helft beginnen
		jmp	level_a
		
leestoets	jsr	kbscan		; lees toetsdruk
		bcc	countdown	; spring indien geen toets gedrukt
		cmp	#75		; test op pijl links
		beq	pijllinks	; ja, spring
		cmp	#77		; test op pijl rechts
		beq	pijlrechts	; ja, spring
		cmp	#80		; test op pijl neer
		beq	pijlneer	; ja, spring
		cpx	#27		; escape gedrukt?
		bne	countdown	; nee, dan verder naar timer routine
		jmp	exit		; ja, dan pleite
countdown	jsr	wait		; wacht 1/18e seconde
		dec	timer		; verlaag timer
		lda	timer		; lees timer
		bne	speel3		; spring indien nog geen seconde voorbij
		dec	time		; verlaag speeltijd
		jsr	printtijd	; werk timer display bij
		lda	time		; controleer op einde tijd
		cmp	#20		; test op 20 seconden
		bpl	countdown1	; indien groter dan verder
;		jsr	timeoutwarning	; geef waarschuwing
countdown1	lda	#18		; laadt timer instelling
		sta	timer		; reset timer
		lda	time		; test of spel voorbij is
		bne	speel3		; ga door indien tijd nog niet voorbij
		jmp	timeout		; de speeltijd is voorbij, game over

pijllinks	jsr	schuiflinks	; schuif naar links
		jmp	countdown	; volgende zet

pijlrechts	jsr	schuifrechts	; schuif naar rechts
		jmp	countdown	; volgende zet

pijlneer	jsr	val		; laat stenen vallen
		txa			; save x register
		pha
		tya			; save y register
		pha
		jsr	zoek		; zoek naar winnende combinaties
		ldy	#9		; laadt rij nummer
		ldx	#9		; laadt kolom index
pijlneer1	jsr	leesveld	; lees veldcode
		cmp	#0		; is het veld leeg?
		beq	pijlneer2	; ja, dan niet verder met controleren
		dex			; verlaag kolom index
		bpl	pijlneer1	; spring indien niet alle kolommen getest
		jmp	gameover	; geen leeg veld, spel voorbij
pijlneer2	pla			; herstel y register
		tay
		pla			; herstel x register
		tax
		jmp 	speel1		; volgende zet

gameover	pla			; maak stack leeg
		pla			; maar doe er niets mee
		jsr	scroll		; laat tekst over het scherm scrollen
		.db	"No fields left *** game over *** Press 'S' to restart *** "
		.db	$EA
		jmp	init		; begin een nieuw spel

timeout		jsr	scroll		; laat tekst over het scherm scrollen
		.db	"No time left *** game over *** Press 'S' to restart *** "
		.db	$EA
		jmp	init		; begin een nieuw spel

kampioen	jsr	scroll		; laat tekst over het scherm scrollen
		.db	"Congratulations, you did it! But how? *** Press 'S' to restart"
		.db	$EA
		jmp	init		; begin een nieuw spel

exit            ldx	#4		; reset scherm en kleur
		jsr	pccom		; via pc-commando
		.db	22,3,17,3
		jsr     wissem          ; wis semafoor
                rts                     ; einde programma

;**********************************************************************
; Subroutine: zetsem
; gewijzigde registers: geen
;**********************************************************************
zetsem		pha			; save accu
		lda	#$0B		; laadt osbyte code
		jsr	osbyte		; test semafoor
                bcc     *-3             ; spring indien gezet
		pla			; herstel accu
		rts			; einde routine

;**********************************************************************
; Subroutine: wissem
; gewijzigde registers: geen
;**********************************************************************
wissem		pha			; save accu
		lda	#$0A		; laadt osbyte code
		jsr	osbyte		; wis semafoor
		pla			; herstel accu
		rts			; einde routine

;**********************************************************************
; Subroutine: pccom
; gewijzigde registers: A,X en Y
; werkruimte: zp, zp+1
;**********************************************************************
pccom		pla			; haal lage byte retour adres van stack
		sta	zp		; zet als lage byte in pointer
		pla			; haal hoge byte retour adres van stack
		sta	zp+1		; zet in pointer
		ldy	#0		; laadt index
pccom1		inc	zp		; verhoog pointer met 1
                bne     *+4             ; spring indien geen pagina grens
		inc	zp+1		; verhoog bij overschrijding pagina grens
                lda     (zp),y          ; lees byte
		jsr	oszend		; stuur naar pc
		dex			; verlaag aantal bytes
		bne	pccom1		; spring indien nog bytes volgen
                inc     zp              ; verhoog pointer met 1
                bne     *+4             ; spring indien geen pagina grens
		inc	zp+1		; verhoog bij overschrijding pagina grens
                jmp     (zp)            ; einde routine

;**********************************************************************
; Subroutine: steen
; input: A=kleur, X en Y = positie van steen in matrix (l.o. is 0,0)
; gewijzigde registers: geen
;**********************************************************************
steen		jsr	zetsem		; zet semafoor
		pha			; bewaar kleurtje op stack
		lda	#17		; zet kleur
		jsr 	oszend
                pla                     ; kleurcode van stack halen
		pha			; kleur nogmaals bewaren
                and     #$0F            ; eventuele maskers verwijderen uit de kleur
		jsr 	oszend
		lda 	#$00		; geef 'xblock f' commando
		jsr	oszend
		lda	#$5A
		jsr	oszend
		lda	#$03
steen1		jsr	oszend
		lda	xlo_l,x		; laadt lage byte van x-positie l.o.
		jsr	oszend		; stuur naar pc
		lda	xlo_h,x		; laadt hoge byte van x-positie l.o.
		jsr	oszend		; stuur naar pc
		lda	ylo_l,y		; laadt lage byte van y-positie l.o.
		jsr	oszend		; stuur naar pc
		lda	ylo_h,y		; laadt hoge byte van y-positie l.o.
		jsr	oszend		; stuur naar pc
		lda	xrb_l,x		; laadt lage byte van x-positie r.b.
		jsr	oszend		; stuur naar pc
		lda	xrb_h,x		; laadt hoge byte van x-positie r.b.
		jsr	oszend		; stuur naar pc
		lda	yrb_l,y		; laadt lage byte van y-positie r.b.
		jsr	oszend		; stuur naar pc
		lda	yrb_h,y		; laadt hoge byte van y-positie r.b.
		jsr	oszend		; stuur naar pc
		pla			; herstel kleurcode
		jmp	wissem		; einde routine via 'wissem'

;**********************************************************************
; Subroutine: markeer
; input: X en Y = positie van steen in matrix (l.o. is 0,0)
; gewijzigde registers: geen
;**********************************************************************
markeer		jsr	zetsem		; zet semafoor
		pha			; bewaar kleurtje op stack
		lda	#17		; zet kleur
		jsr 	oszend
		lda	#15		; fel wit
		jsr 	oszend
		lda 	#$00		; geef 'xblock o' commando
		jsr	oszend
		lda	#$5A
		jsr	oszend
		lda	#$02
		bne	steen1		; springt altijd

;**********************************************************************
; Tabel: matrix coordinaten
;**********************************************************************

xlo_l		.db	20,56,92,128,164,200,236,16,52,88
xlo_h		.db	0,0,0,0,0,0,0,1,1,1
ylo_l		.db	153,119,85,51,17,239,205,171,137,103,50
ylo_h		.db	1,1,1,1,1,0,0,0,0,0,0
xrb_l		.db	52,88,124,160,196,232,12,48,84,120
xrb_h		.db	0,0,0,0,0,0,1,1,1,1
yrb_l		.db	121,87,53,19,241,207,173,139,105,71,18
yrb_h		.db	1,1,1,1,0,0,0,0,0,0,0

;**********************************************************************
; Subroutine: random
; input: A = maximale waarde
; output: A = random getal tussen 1 ... (input)
; gewijzigde registers: A
; werkruimte: zp
;**********************************************************************
random		sta	zp		; bewaar maximale waarde
		tya			; bewaar y register
		pha
		ldy	#32		; laadt teller voor aantal bewerkingen
random1		lda	$10		; laadt accu met waarde van random geheugen
		lsr	a		; vermenigvuldig met 16
		lsr	a
		lsr	a
		lsr	a
		eor	$0C		; voer bewerking uit met laatste random geheugen
		ror	a		; roteer rechts met carry
		rol	$08		; schuif random geheugen
		rol	$09
		rol	$0A
		rol	$0B
		rol	$0C
		dey			; verlaag teller met 1
		bne	random1		; spring indien bewerking nog een keer uitvoeren
		pla			; herstel y register
		tay
		lda	$08		; laadt random getal
		and	#$0F		; alleen lage nibble gebruiken
		sec			; zet carry voor aftrekken
random2		sbc	zp		; trek maximale waarde ervan af
		bpl	random2		; opnieuw aftrekken indien nog niet klaar ;-)
		clc			; wis carry voor optellen
		adc	zp		; bepaal modulo
		clc			; wis carry voor optellen
		adc	#1		; tel er 1 bij op want 1 <= RND <= max
		rts			; einde random routine

;**********************************************************************
; Subroutine: hex2dec
; input: Y = pointer naar hexadecimaal getal in zeropage
; output: string op decimaal
; gewijzigde registers: geen
; werkruimte: zp .. zp+3
;**********************************************************************
hex2dec		pha			; save accu 
		txa			; x register naar accu
		pha			; ook op stack saven
		ldx	#0		; laadt teller
hex2dec1	lda	$00,y		; laadt getal
		sta	zp,x		; zet in werkruimte
		iny			; verhoog index
		inx			; verhoog teller
		cpx	#4		; test op einde copieren
		bne	hex2dec1	; spring indien nog niet alle bytes gecopieerd
		ldx	#9		; laadt teller
hex2dec2	lda	#0		; laadt accu
		sta	decimaal,x	; reset resultaat plaats
hex2dec3	sec			; zet carry voor aftrekken
		lda	zp		; laadt lage byte om te zetten waarde
		sbc	hdt1,x		; trek er lage byte tabel vanaf
		pha			; zet op stack
		lda	zp+1		; laadt een na laagste byte om te zetten waarde
		sbc	hdt2,x		; trek er een na laagste byte tabel vanaf
		pha			; zet op stack
		lda	zp+2		; laadt een na hoogste byte om te zetten waarde
		sbc	hdt3,x		; trek er een na hoogste byte tabel vanaf
		pha			; zet op stack
		lda	zp+3		; laadt hoge byte om te zetten waarde
		sbc	hdt4,x		; trek er hoge byte tabel vanaf
		bcc	hex2dec4	; spring indien volgende tabel waarde afgetrokken wordt
		sta	zp+3		; zet resultaat terug
		pla			; een na hoge byte terughalen
		sta	zp+2		; zet terug
		pla			; een na lage byte terughalen
		sta	zp+1		; zet terug
		pla			; laagste byte terughalen
		sta	zp		; zet terug
		inc	decimaal,x	; verhoog print geheugen met 1
		bne	hex2dec3	; springt altijd
hex2dec4	pla			; volgende factor, resultaat niet meer nodig
		pla			; niet meer nodig
		pla			; ook niet meer nodig
		dex			; verlaag karakteraantal met 1
		bpl	hex2dec2	; nog niet allemaal gehad, ga door
		pla			; haal x register terug van stack
		tax			; accu dus naar x zetten
		pla			; accu ook terughalen
		rts			; einde routine

;**********************************************************************
; Tabel: hex2dec tabel
;**********************************************************************
hdt1		.db	$01,$0A,$64,$E8,$10,$A0,$40,$80
hdt2		.db	$00,$00,$00,$03,$27,$86,$42,$96,$E1,$CA
hdt3		.db	$00,$00,$00,$00,$00,$01,$0F,$98,$F5,$9A
hdt4		.db	$00,$00,$00,$00,$00,$00,$00,$00,$05,$3B


;**********************************************************************
; Subroutine: val - laat stenen zakken van speelrij naar matrix
; gewijzigde registers: geen
;**********************************************************************
val		pha			; bewaar registers op stack
		txa
		pha
		tya
		pha
		ldx	#0		; laadt kolom pointer
val1		ldy	#9		; laadt rij pointer
val2		jsr	leesveld	; lees inhoud van (x,y)
		cmp	#0		; kijk of het veld leeg is
		bne	val3		; spring indien veld niet leeg
		iny			; tijdelijk naar bovenliggend veld
		jsr	leesveld	; lees de waarde van bovenliggend veld
		pha			; bewaar even op stack
		lda	#0		; laadt kleur zwart
		jsr	zetveld		; zet nieuwe code in't veld
		jsr	steen		; wis veld
		pla			; herstel oude kleur
		dey			; weer naar het te kleuren veld
		jsr	zetveld
		jsr	steen		; kleur het veld
		dey			; verlaag rij pointer voor volgende rij
		bpl	val2		; spring indien nog niet beneden
val3            inx                     ; verhoog kolom pointer
		cpx 	#10		; alle kolommen gehad?
		bne	val1		; nee, dan volgende
		pla			; herstel registers
		tay
		pla
		tax
		pla
		rts			; einde routine

;**********************************************************************
; Subroutine: leesveld - leest kleurcode van (x,y)
; gewijzigde registers: A = kleurcode 
; werkruimte: zp
;**********************************************************************
leesveld	cpy	#10		; test op uitlezen van speelrij
		beq	leesrij		; zo ja, dan andere routine
		sty	zp		; zet y coordinaat in werkruimte
		txa			; zet x coordinaat in accu
		asl	a		; vermenigvuldig met 16
		asl	a
		asl	a
		asl	a
		clc			; wis carry voor optellen
		adc	zp		; tel y coordinaat erbij
		tay			; zet accu als index in y register
		lda	veld,y		; lees kleurcode uit geheugen
		ldy	zp		; herstel y register
		rts			; einde routine

leesrij		lda	rij,x		; lees kleur uit rij
		rts			; einde routine

;**********************************************************************
; Subroutine: zetveld - zet kleurcode in (x,y)
; gewijzigde registers: geen 
; werkruimte: zp
;**********************************************************************
zetveld		cpy	#10		; test op zetten van speelrij
		beq	zetrij		; zo ja, dan andere routine
		pha			; bewaar veldcode
		sty	zp		; zet y coordinaat in werkruimte
		txa			; zet x coordinaat in accu
		asl	a		; vermenigvuldig met 16
		asl	a
		asl	a
		asl	a
		clc			; wis carry voor optellen
		adc	zp		; tel y coordinaat erbij
		tay			; zet accu als index in y register
		pla			; herstel veldcode
		sta	veld,y		; zet veldcode in geheugen
		ldy	zp		; herstel y register
		rts			; einde routine

zetrij		sta	rij,x		; zet kleur in rij
		rts			; einde routine

;**********************************************************************
; Subroutine: schuiflinks - roteert speelbalk eenmaal links
; gewijzigde registers: geen
;**********************************************************************
schuiflinks	pha			; bewaar registers op stack
		txa
		pha
		tya
		pha
		ldx	#0		; laadt horizontale teller
		ldy	#10		; laadt vertikale pointer voor 'steen' routine
		lda	rij		; lees kleur op eerste veld
		pha			; bewaar op den stack
links1		lda	rij+1,x		; lees waarde van rechts gelegen veld
		sta	rij,x		; zet in huidige veld
		jsr	steen		; kleur het huidige veld
		inx			; verhoog teller
		cpx	#9		; laatste veld bereikt?	
		bne	links1		; nee, dan volgende veld
		pla			; haal oude waarde van eerste veld terug
		sta	rij+9		; zet in laatste veld
		jsr	steen		; kleur veld op het scherm
		pla			; herstel registers
		tay
		pla
		tax
		pla
		rts			; einde routine

;**********************************************************************
; Subroutine: schuifrechts - roteert speelbalk eenmaal rechts
; gewijzigde registers: geen
;**********************************************************************
schuifrechts	pha			; bewaar registers op stack
		txa
		pha
		tya
		pha
		ldx	#9		; laadt horizontale teller
		ldy	#10		; laadt vertikale pointer voor 'steen' routine
		lda	rij+9		; lees kleur van laatste veld
		pha			; bewaar op den stack
rechts1		lda	rij-1,x		; lees waarde van links gelegen veld
		sta	rij,x		; zet in huidige veld
		jsr	steen		; kleur het huidige veld
		dex			; verlaag teller
		cpx	#0		; laatste veld bereikt?	
		bne	rechts1		; nee, dan volgende veld
		pla			; haal oude waarde van eerste veld terug
		sta	rij		; zet in eerste veld
		jsr	steen		; kleur veld op het scherm
		pla			; herstel registers
		tay
		pla
		tax
		pla
		rts			; einde routine

;**********************************************************************
; Subroutine: kbscan - toetsenbord scan
; Uitvoer:  Carry = keyboard status (0=geen toets)
;           X = ascii waarde -als toets gedrukt-
;           A = scancode -als toets gedrukt-
; gewijzigde registers: A en X 
;**********************************************************************
kbscan		jsr	zetsem		; zet semafoor
		lda	#$00		; geef pc-commando #5D
		jsr	oszend
		lda	#$5D
		jsr	oszend
		jsr	oslees		; lees statuscode
		ror	a		; schuif key-pressed bit in carry
		php			; save carry bit (status reg)
		bcc	kbscan1		; spring indien geen toets gedrukt is
		jsr	oslees		; lees ascii waarde
		tax			; zet in x register
		jsr	oslees		; lees scancode
kbscan1		jsr	wissem		; wis semafoor
		plp			; herstel carry bit (status reg)
		rts			; einde routine			

;**********************************************************************
; Subroutine: zet doelen
; input: A = level
; gewijzigde registers: A
;**********************************************************************
zetdoelen	asl	a		; vermenigvuldig met 4
		asl	a
		tay			; zet als index
		lda	doeltab,y	; laadt doel-aantal 1
		sta	goal1		; zet in teller
		lda	doeltab+1,y	; laadt doel-aantal 2
		sta	goal2		; zet in teller
		lda	doeltab+2,y	; laadt doel-aantal 3
		sta	goal3		; zet in teller
		lda	doeltab+3,y	; laadt doel-aantal 4
		sta	goal4		; zet in teller
		rts			; einde routine

;**********************************************************************
; Tabel: doeltab - aantal goals per level
;**********************************************************************
doeltab		.db	5,10,5,5
		.db	10,5,5,5
		.db	5,5,10,5
		.db	5,5,5,10
		.db	10,10,10,10

;**********************************************************************
; Subroutine: printscore
; gewijzigde registers: geen
; werkruimte: zp+2 .. zp+7
;**********************************************************************
printscore	pha			; bewaar registers op stack
		txa
		pha
		tya
		pha
		ldy	#score		; laadt index naar score
		jsr	hex2dec		; reken om naar digits
		lda	#170		; zet x coordinaat
		sta	zp+7
		lda	#1
		sta	zp+6
		lda 	#91		; zet y coordinaat
		sta	zp+5
		lda	#0
		sta	zp+4
		ldy	#6		; laadt aantal digits
printdecimaal	sty	zp+3		; zet in teller
		jsr	zetsem		; zet semafoor
print0		ldx	#pdt1e-pdt1b	; laadt aantal te zenden bytes
		jsr	pccom		; geef pc-commando's
pdt1b		.db	17,0		; digit kleur zwart (oude digit wissen)
		.db	$00,$08,3,2	; tsize 3,2
		.db 	$00,$07		; print string commando
pdt1e		ldx 	#3		; laadt teller
print1		lda	zp+4,x		; lees coordinaat
		jsr	oszend		; stuur naar pc
		dex			; verlaag teller
		bpl	print1		; spring indien nog bytes volgen
		ldx	#pdt2e-pdt2b	; laadt aantal te zenden bytes
		jsr	pccom		; geef pc-commando's
pdt2b		.db	1,0		; print "zwart blokje"
		.db	17,3		; digit kleur 
		.db 	$00,$07		; print string commando
pdt2e		ldx 	#3		; laadt teller
print2		lda	zp+4,x		; lees coordinaat
		jsr	oszend		; stuur naar pc
		dex			; verlaag teller
		bpl	print2		; spring indien nog bytes volgen
		ldy	zp+3		; lees decimaal pointer
		lda	decimaal,y	; lees decimaal teken
		beq	print4		; spring indien "voorloop-nul"
print3		clc			; wis carry voor optellen
		adc	#'0'		; bereken ascii waarde van digit
		sta	zp+2		; zet vlag voor 0-afdrukken
		jsr	oszend		; stuur naar pc
		bne	print5
print4		cpy	#0		; indien laatste digit dan wel '0' printen
		beq	print3
		lda	zp+2		; laadt voorloopnul-vlag
		beq	print5		; spring bij voorloopnul
		lda	#0		; 0 afdrukken indien midden in getal
		beq	print3		; gedwongen sprong
print5		lda	#0		; stuur afsluitende code voor print string commando
		jsr	oszend
		clc			; verhoog x coordinaat van getal
		lda	zp+7		; laadt lage byte
		adc	#24		; tel er de digitbreedte bij op
		sta	zp+7		; zet terug
		lda	zp+6		; laadt hoge byte
		adc	#0		; tel eventuele carry erbij
		sta	zp+6		; zet resultaat terug
		dec	zp+3		; verlaag digit pointer
		bpl	print0		; spring indien nog digit volgen
		jsr	wissem		; wis semafoor
		pla			; herstel registers
		tay
		pla
		tax
		pla
		rts			; einde routine

;**********************************************************************
; Subroutine: printlevel
; gewijzigde registers: geen
; werkruimte: zp+2 .. zp+7
;**********************************************************************
printlevel	pha			; bewaar registers op stack
		txa
		pha
		tya
		pha
		ldy	#level		; laadt index naar score
		jsr	hex2dec		; reken om naar digits
		lda	#154		; zet x coordinaat
		sta	zp+7
		lda	#1
		sta	zp+6
		lda 	#200		; zet y coordinaat
		sta	zp+5
		lda	#0
		sta	zp+4
		ldy	#2		; laadt aantal digits
		jmp	printdecimaal	; ga verder met afdrukken

;**********************************************************************
; Subroutine: printtijd
; gewijzigde registers: geen
; werkruimte: zp+2 .. zp+7
;**********************************************************************
printtijd	pha			; bewaar registers op stack
		txa
		pha
		tya
		pha
		ldy	#time		; laadt index naar time
		jsr	hex2dec		; reken om naar digits
		lda	#18		; zet x coordinaat
		sta	zp+7
		lda	#2
		sta	zp+6
		lda 	#200		; zet y coordinaat
		sta	zp+5
		lda	#0
		sta	zp+4
		ldy	#2		; laadt aantal digits
		jmp	printdecimaal	; ga verder met afdrukken

;**********************************************************************
; Subroutine: printgoal -
; gewijzigde registers: geen
; werkruimte: zp+2 .. zp+7
;**********************************************************************
printgoal1	pha			; bewaar registers op stack
		txa
		pha
		tya
		pha
		ldy	#goal1		; laadt index naar goal1
		jsr	hex2dec		; reken om naar digits
		lda	#155		; zet x coordinaat
		sta	zp+7
		lda	#1
		sta	zp+6
		lda 	#47		; zet y coordinaat
		sta	zp+5
		lda	#1
		sta	zp+4
		ldy	#2		; laadt aantal digits
		jmp	printdecimaal	; ga verder met afdrukken

;**********************************************************************
; Subroutine: printgoal |
; gewijzigde registers: geen
; werkruimte: zp+2 .. zp+7
;**********************************************************************
printgoal2	pha			; bewaar registers op stack
		txa
		pha
		tya
		pha
		ldy	#goal2		; laadt index naar goal2
		jsr	hex2dec		; reken om naar digits
		lda	#14		; zet x coordinaat
		sta	zp+7
		lda	#2
		sta	zp+6
		lda 	#47		; zet y coordinaat
		sta	zp+5
		lda	#1
		sta	zp+4
		ldy	#2		; laadt aantal digits
		jmp	printdecimaal	; ga verder met afdrukken

;**********************************************************************
; Subroutine: printgoal /
; gewijzigde registers: geen
; werkruimte: zp+2 .. zp+7
;**********************************************************************
printgoal3	pha			; bewaar registers op stack
		txa
		pha
		tya
		pha
		ldy	#goal3		; laadt index naar goal3
		jsr	hex2dec		; reken om naar digits
		lda	#155		; zet x coordinaat
		sta	zp+7
		lda	#1
		sta	zp+6
		lda 	#114		; zet y coordinaat
		sta	zp+5
		lda	#1
		sta	zp+4
		ldy	#2		; laadt aantal digits
		jmp	printdecimaal	; ga verder met afdrukken

;**********************************************************************
; Subroutine: printgoal \
; gewijzigde registers: geen
; werkruimte: zp+2 .. zp+7
;**********************************************************************
printgoal4	pha			; bewaar registers op stack
		txa
		pha
		tya
		pha
		ldy	#goal4		; laadt index naar goal4
		jsr	hex2dec		; reken om naar digits
		lda	#14		; zet x coordinaat
		sta	zp+7
		lda	#2
		sta	zp+6
		lda 	#114		; zet y coordinaat
		sta	zp+5
		lda	#1
		sta	zp+4
		ldy	#2		; laadt aantal digits
		jmp	printdecimaal	; ga verder met afdrukken

;**********************************************************************
; Subroutine: zoek
; gewijzigde registers: geen
; werkruimte: zp+1, zp+8, zp+9
;**********************************************************************
zoek		pha			; bewaar registers op stack
		txa
		pha
		tya
		pha
zoek0		ldx	#0		; zet x pointer naar linker kolom
                stx     zp+9            ; reset vlag voor gevonden combinaties
zoek1		ldy	#0		; zet y pointer naar eerste rij
zoek2		jsr	leesveld	; lees waarde van cel
		cmp	#0		; is de cel leeg?
		beq	volgende_kolom	; ja, dan spring
		sta	zp+8		; bewaar veldinhoud op stack
		and	#maskgoal1	; test of cel al deel uitmaakt van goal1
		bne	zoek3		; ja, dan niet verder controleren
		lda	zp+8		; herstel veldinhoud
		jsr	zoekgoal1	; test of goal1 voorkomt
zoek3		lda	zp+8		; herstel veldinhoud
		and	#maskgoal2	; test of cel al deel uitmaakt van goal2
		bne	zoek4		; ja, dan niet verder controleren
		lda	zp+8		; herstel veldinhoud
		jsr	zoekgoal2	; idem voor goal2
zoek4		lda	zp+8		; herstel veldinhoud
		and	#maskgoal3	; test of cel al deel uitmaakt van goal3
		bne	zoek5		; ja, dan niet verder controleren
		lda	zp+8		; herstel veldinhoud
		jsr	zoekgoal3	; idem voor goal3
zoek5		lda	zp+8		; herstel veldinhoud
	 	and	#maskgoal4	; test of cel al deel uitmaakt van goal4
		bne	volgende_rij	; ja, dan niet verder controleren
		lda 	zp+8		; herstel veldinhoud
		jsr	zoekgoal4	; idem voor goal4
volgende_rij	iny			; verhoog rij nummer
		cpy	#10		; test op laatste rij
		bne	zoek2		; begin aan een nieuwe rij
volgende_kolom	inx			; verhoog kolom nummer
		cpx	#10		; laatste kolom gehad
		bne	zoek1		; nee, dan deze kolom uitlezen
                ldx     #0              ; reset kolom pointer
zoek6           ldy     #0              ; reset rij pointer
zoek7           jsr     leesveld        ; lees veldinhoud
                and     #$F0            ; test of veld deel uitmaakt van gevonden combinatie
                beq     zoek8           ; nee, dan volgende cel testen
                lda     #0              ; wis cel
                jsr     steen           ; - op het scherm
                jsr     zetveld         ; - in het geheugen
                tya                     ; bewaar rij nummer op stack
                pha
kletter         iny                     ; verhoog rij nummer
                jsr     leesveld        ; lees de inhoud van die cel
                dey                     ; verlaag rij nummer
                jsr     zetveld         ; zet celinhoud van bovenstaande cel
                jsr     steen           ; kleur cel op het scherm
                iny                     ; verhoog rij nummer
                cpy     #9              ; bij een na hoogste rij aangekomen?
                bmi     kletter         ; laat nog meer naar beneden kletteren
                lda     #0              ; de bovenste cel moet leeg worden
                jsr     zetveld         ; regel dat in de matrix
                jsr     steen           ; en maak um zwart op het scherm
                pla                     ; herstel rij nummer
                tay
                jmp     zoek7           ; test cel opnieuw, er kan een gemarkeerde cel in gevallen zijn
zoek8           iny                     ; verhoog rij pointer
                cpy     #10             ; test op bovenste rij
                bne     zoek7           ; ga verder voor volgende rij
                inx                     ; verhoog kolom pointer
                cpx     #10             ; test op laatste kolom
                bne     zoek6           ; spring voor volgende kolom
                lda     zp+9            ; controleer of er combinaties gevonden zijn
                beq     zoek9		; nee, stop routine
		jmp	zoek0           ; ja, ga verder zoeken
zoek9		pla			; herstel registers
		tay
		pla
		tax
		pla
		rts

;**********************************************************************
; Subroutine: verhoogscore
; input: A = aantal punten
; gewijzigde registers: geen
;**********************************************************************
verhoogscore	pha			; save accu
		clc			; wis carry voor optellen
		adc	score		; tel lage byte erbij
		sta	score		; berg op
		lda	score+1		; werk een na laagste byte bij
		adc	#0
		sta	score+1
		lda	score+2		; werk een na hoogste byte bij
		adc	#0
		sta	score+2
		lda	score+3		; werk hoogste byte bij
		adc	#0
		sta	score+3
		jsr	printscore	; werk score display bij
		pla			; herstel accu
		rts			; einde routine

;**********************************************************************
; Subroutine: zoekgoal1 (-)
; input: A = kleurcode huidige cel met statusmasker in hoge nibble
; gewijzigde registers: geen
; werkruimte: 	zp+1 	= kleurcode zonder statusmasker
;		zp+2	= score teller
;		zp+10	= save x
;		zp+11	= save y
; 		zp+9	= vlag voor gevonden combinatie
;**********************************************************************
zoekgoal1	pha			; save accu
		stx	zp+10		; bewaar registers op stack
		sty	zp+11
		and	#$0F		; wis statusmasker in hoge nibble
		sta	zp+1		; zet in werkgeheugen
		lda	#0		; reset score
		sta	zp+2		; zet in teller
zgoal1		inc	zp+2		; verhoog score teller
		inx			; verhoog kolom teller
		cpx	#10		; rechter kolom bereikt?
		beq	markgoal1	; dan naar markeer routine
		jsr	leesveld	; lees kleurcode van rechts gelegen veld
		and	#$0F		; negeer eventuele statusbits
		cmp	zp+1		; vergelijk met gezochte kleurcode
		beq	zgoal1		; zoek verder indien gelijk
markgoal1	lda	zp+2		; laadt score (=aantal te markeren cellen)
		cmp	minlengte	; vergelijk met vereiste lengte
		bmi	zgoal3		; spring indien te weinig blokjes
		pha			; zet score op stack
		ldx	zp+10		; lees startpositie in x
zgoal2		jsr	markeer		; markeer de cel met witte rand
		jsr	leesveld	; lees de cel
		ora	#maskgoal1	; maskeer de cel
		jsr	zetveld		; schrijf gemarkeerde waarde terug in cel
		inx			; verhoog kolomnummer
		dec	zp+2		; verlaag aantal te markeren cellen
		lda	zp+2		; laadt aantal te markeren cellen
		bne	zgoal2		; spring indien nog cellen volgen
		pla			; haal gescoord resultaat van stack
		jsr	verhoogscore	; verhoog de score
		inc	zp+9		; verhoog aantal gevonden combinaties
		lda	goal1		; laadt aantal goals te gaan
		beq	zgoal3		; indien reeds 0 dan niets doen
		dec	goal1		; verlaag aantal goals to go
		jsr	printgoal1	; werk display bij
zgoal3		ldx	zp+10		; herstel x register
		ldy	zp+11		; herstel y register
		pla			; herstel accu
		rts

;**********************************************************************
; Subroutine: zoekgoal2 (|)
; input: A = kleurcode huidige cel met statusmasker in hoge nibble
; gewijzigde registers: geen
; werkruimte: 	zp+1 	= kleurcode zonder statusmasker
;		zp+2	= score teller
;		zp+10	= save x
;		zp+11	= save y
; 		zp+9	= vlag voor gevonden combinatie
;**********************************************************************
zoekgoal2	pha			; save accu
		stx	zp+10		; bewaar registers op stack
		sty	zp+11
		and	#$0F		; wis statusmasker in hoge nibble
		sta	zp+1		; zet in werkgeheugen
		lda	#0		; reset score
		sta	zp+2		; zet in teller
zgoal4		inc	zp+2		; verhoog score teller
		iny			; verhoog rij teller
		cpy	#10		; bovenste rij bereikt?
		beq	markgoal2	; dan naar markeer routine
		jsr	leesveld	; lees kleurcode van rechts gelegen veld
		and	#$0F		; negeer eventuele statusbits
		cmp	zp+1		; vergelijk met gezochte kleurcode
		beq	zgoal4		; zoek verder indien gelijk
markgoal2	lda	zp+2		; laadt score (=aantal te markeren cellen)
		cmp	minlengte	; vergelijk met vereiste lengte
		bmi	zgoal6		; spring indien te weinig blokjes
		pha			; bewaar score op stack
		ldy	zp+11		; lees startpositie in y
zgoal5		jsr	markeer		; markeer de cel met witte rand
		jsr	leesveld	; lees de cel
		ora	#maskgoal2	; maskeer de cel
		jsr	zetveld		; schrijf gemarkeerde waarde terug in cel
		iny			; verhoog rijnummer
		dec	zp+2		; verlaag aantal te markeren cellen
		lda	zp+2		; laadt aantal te markeren cellen
		bne	zgoal5		; spring indien nog cellen te gaan
		pla			; haal gescoord resultaat terug
		jsr	verhoogscore	; werk de score bij
		inc	zp+9		; verhoog aantal gevonden combinaties
		lda	goal2		; laadt aantal goals te gaan
		beq	zgoal6		; indien reeds 0 dan niets doen
		dec	goal2		; verlaag aantal goals to go
		jsr	printgoal2	; werk display bij
zgoal6		ldx	zp+10		; herstel x register
		ldy	zp+11		; herstel y register
		pla			; herstel accu
		rts

;**********************************************************************
; Subroutine: zoekgoal3 (/)
; input: A = kleurcode huidige cel met statusmasker in hoge nibble
; gewijzigde registers: geen
; werkruimte: 	zp+1 	= kleurcode zonder statusmasker
;		zp+2	= score teller
;		zp+10	= save x
;		zp+11	= save y
; 		zp+9	= vlag voor gevonden combinatie
;**********************************************************************
zoekgoal3	pha			; save accu
		stx	zp+10		; bewaar registers op stack
		sty	zp+11
		and	#$0F		; wis statusmasker in hoge nibble
		sta	zp+1		; zet in werkgeheugen
		lda	#0		; reset score
		sta	zp+2		; zet in teller
zgoal7		inc	zp+2		; verhoog score teller
		iny			; verhoog rij teller
		cpy	#10		; bovenste rij bereikt?
		beq	markgoal3	; dan naar markeer routine
		inx			; verhoog kolom teller
		cpx	#10		; rechter kolom bereikt?
		beq	markgoal3	; dan naar markeer routine
		jsr	leesveld	; lees kleurcode van rechts gelegen veld
		and	#$0F		; negeer eventuele statusbits
		cmp	zp+1		; vergelijk met gezochte kleurcode
		beq	zgoal7		; zoek verder indien gelijk
markgoal3	lda	zp+2		; laadt score (=aantal te markeren cellen)
		cmp	minlengte	; vergelijk met vereiste lengte
		bmi	zgoal9		; spring indien te weinig blokjes
		pha			; bewaar score op stack
		ldx	zp+10		; lees start kolom in x
		ldy	zp+11		; lees startrij in y
zgoal8		jsr	markeer		; markeer de cel met witte rand
		jsr	leesveld	; lees de cel
		ora	#maskgoal3	; maskeer de cel
		jsr	zetveld		; schrijf gemarkeerde waarde terug in cel
		inx			; verhoog kolomnummer
		iny			; verhoog rijnummer
		dec	zp+2		; verlaag aantal te markeren cellen
		lda	zp+2		; laadt aantal te markeren cellen
		bne	zgoal8		; spring indien nog cellen te gaan
		pla			; haal gescoord resultaat van stack
		jsr	verhoogscore	; verhoog de score
		inc	zp+9		; verhoog aantal gevonden combinaties
		lda	goal3		; laadt aantal goals te gaan
		beq	zgoal9		; indien reeds 0 dan niets doen
		dec	goal3		; verlaag aantal goals to go
		jsr	printgoal3	; werk display bij
zgoal9		ldx	zp+10		; herstel x register
		ldy	zp+11		; herstel y register
		pla			; herstel accu
		rts

;**********************************************************************
; Subroutine: zoekgoal4 (\)
; input: A = kleurcode huidige cel met statusmasker in hoge nibble
; gewijzigde registers: geen
; werkruimte: 	zp+1 	= kleurcode zonder statusmasker
;		zp+2	= score teller
;		zp+10	= save x
;		zp+11	= save y
; 		zp+9	= vlag voor gevonden combinatie
;**********************************************************************
zoekgoal4	pha			; save accu
		stx	zp+10		; bewaar registers op stack
		sty	zp+11
		and	#$0F		; wis statusmasker in hoge nibble
		sta	zp+1		; zet in werkgeheugen
		lda	#0		; reset score
		sta	zp+2		; zet in teller
zgoal10		inc	zp+2		; verhoog score teller
		dey			; verlaag rij teller
		cpy	#-1		; onderste rij bereikt?
		beq	markgoal4	; dan naar markeer routine
		inx			; verlaag kolom teller
		cpx	#10		; rechter kolom bereikt?
		beq	markgoal4	; dan naar markeer routine
		jsr	leesveld	; lees kleurcode van rechts gelegen veld
		and	#$0F		; negeer eventuele statusbits
		cmp	zp+1		; vergelijk met gezochte kleurcode
		beq	zgoal10		; zoek verder indien gelijk
markgoal4	lda	zp+2		; laadt score (=aantal te markeren cellen)
		cmp	minlengte	; vergelijk met vereiste lengte
		bmi	zgoal12		; spring indien te weinig blokjes
		pha			; zet score op stack
		ldx	zp+10		; lees startkolom in x
		ldy	zp+11		; lees startrij in y
zgoal11		jsr	markeer		; markeer de cel met witte rand
		jsr	leesveld	; lees de cel
		ora	#maskgoal4	; maskeer de cel
		jsr	zetveld		; schrijf gemarkeerde waarde terug in cel
		dey			; verlaag rijnummer
		inx			; verhoog kolomnummer
		dec	zp+2		; verlaag aantal te markeren cellen
		lda	zp+2		; laadt aantal te markeren cellen
		bne	zgoal11		; spring indien nog cellen te gaan
		pla			; haal gescoord resultaat van stack
		jsr	verhoogscore	; verhoog de score
		inc	zp+9		; verhoog aantal gevonden combinaties
		lda	goal4		; laadt aantal goals te gaan
		beq	zgoal12		; indien reeds 0 dan niets doen
		dec	goal4		; verlaag aantal goals to go
		jsr	printgoal4	; werk display bij
zgoal12		ldx	zp+10		; herstel x register
		ldy	zp+11		; herstel y register
		pla			; herstel accu
		rts

;**********************************************************************
; Subroutine: timeout warning
; gewijzigde registers: A, X en Y
; werkruimte: 	zp ... zp+3
;**********************************************************************
timeoutwarning	pha			; save gebruikte registers
		txa
		pha
		jsr	zetsem		; zet semafoor
		ldx	#40		; laadt teller
		jsr 	pccom		; geef commando
		.db	31,10,27	; cursor naar 10,27
		.db	"Warning: you're running out of time !"
		.db	$EA
		jsr	wissem		; reset semafoor
		pla			; herstel registers
		tax
		pla
		rts			; einde routine

;**********************************************************************
; Subroutine: scroll
; gewijzigde registers: A, X en Y
; werkruimte: 	zp ... zp+3
;**********************************************************************
scroll		pla			; haal lage byte retour adres van stack
		sta	zp		; zet als lage byte in pointer
		pla			; haal hoge byte retour adres van stack
		sta	zp+1		; zet in pointer
		ldy	#0		; laadt index
		ldx	#0		; reset pointer
scroll1		inc	zp		; verhoog pointer met 1
                bne     *+4             ; spring indien geen pagina grens
		inc	zp+1		; verhoog bij overschrijding pagina grens
                lda     (zp),y          ; lees byte
		bmi	scroll2		; spring indien einde routine ontdekt
		sta	scrollmsg,x	; berg op in scroll tekst
		inx			; verhoog pointer
		jmp	scroll1		; ga verder voor volgend teken
scroll2		lda	#17		; zet kleur 
		jsr	oszend
		lda	#15		; fel wit
		jsr	oszend
		lda	#" "		; laadt code voor spatie
scroll3		cpx	#60		; test op minimale string lengte
		bpl 	scroll4		; spring indien langer dan minimale lengte
		sta	scrollmsg,x	; vul string aan met spatie
		inx			; verhoog teller
		bne	scroll3		; ga door totdat minimale lengte bereikt is
scroll4		stx	zp+2		; berg berichtlengte op in werkgeheugen
		ldx	#-1		; laadt bericht pointer
		stx	zp+3		; zet beginpositie in geheugen
scroll5		jsr	zetsem		; zet semafoor
		ldy 	#0		; laadt scroll teller
		lda	#31		; geef cursor commando aan pc (vdu 31,x,y)
		jsr	oszend
		lda	#10		; horizontale positie op 10
		jsr	oszend
		lda	#27		; vertikale positie op 27
		jsr	oszend
		jsr	wissem		; wis semafoor
		inc	zp+3		; verhoog beginpositie in bericht
		ldx	zp+3		; laadt beginpositie
		cpx	zp+2		; test op einde bericht
		bne	scroll6		; niet laatste positie, ga tekst afdrukken
		ldx	#0		; reset beginpositie
		stx	zp+3		; ook in geheugen
scroll6		lda	scrollmsg,x	; laadt karakter
		jsr	oszend		; stuur naar pc
		inx			; verhoog pointer
		cpx	zp+2		; einde bericht bereikt?
		bne	scroll7		; nee, dan verder gaan
		ldx	#0		; reset pointer
scroll7		iny			; verhoog teller
		cpy	#60		; vensterbreedte bereikt?
		bne	scroll6		; nee, dan volgende karakter afdrukken
		jsr	kbscan		; test of toets gedrukt is
		bcc	scroll8		; geen toets gedrukt, ga wachten
		cpx	#'S'		; is de 'S' toets gedrukt
		beq	scroll9		; ja, dan terug naar het spel
		cpx	#'s'		; is de 's' toets gedrukt
		beq	scroll9		; ja, dan terug naar het spel
		cpx	#27		; is de 'escape' toets gedrukt
		bne	scroll8		; nee, ga dan wachten
		jmp	exit		; spel afsluiten, speler heeft geen zin meer		
scroll8		jsr	wait		; wacht 1/18e seconde
		jsr	wait		; en nog effe wachten
		jmp	scroll5		; ga volgende stap scrollen
scroll9         jsr	zetsem		; zet semafoor
		lda	#31		; zet de cursor aan het begin van de scrollbalk
		jsr	oszend
		lda 	#10		; x positie op 10
		jsr 	oszend
		lda	#27		; y positie op 27
		jsr	oszend
		jsr	wissem		; reset semafoor
		lda	#' '		; laadt spatie
		ldy 	#60		; laadt regellengte
scroll10	jsr 	oszend		; print spatie
		dey			; verlaag teller
		bpl	scroll10	; spring indien regel nog niet helemaal leeg is
		jmp     (zp)            ; einde routine

scrollmsg	equ	*		; dit moet laatste regel van programma zijn!
