;:sys36864
	;.opt oo
; **** sprite-killer
; nikolaus heusler, XXXXXXXXXXXX XX, XXXX XXXXXXXX XX
; nach james host
; (c) nh 6.92
; **** label-deklarationen
	*=$cce5 	; startadresse 52453
mobmem	=$d200 	; gespiegelte sprite-daten
ierr	=$300 	; direktmodus-vektor
nmiv	=$318 	; restore-vektor
ibsout	=$326 	; ausgabevektor
vic	=$d000 	; videobaustein
tast	=$dc00 	; tastaturauswertung
ciairq	=$dc0d 	; irq freigabe
bank	=$dd00 	; vic-speicherbereich
port	=1 	; 6510-speicherbereich
tmp	=$fb 	; zwischenspeicher $fb..$fe
restor	=$ff8a 	; vektoren initialisieren
; **** beginn hauptprogramm
	sei
	jsr restor 	; vektoren initialisieren
	lda ibsout 	; alten ausgabevektor merken
	sta active 	; betrieb sperren
	sta ju2+1
	lda ibsout+1
	sta ju2+2
	lda ierr 	; direktmodus-vektor merken
	sta ju1+1
	lda ierr+1
	sta ju1+2
	lda #<vec3 	; neuen direktmodus-vektor
	sta ierr 	; setzen
	lda #>vec3
	sta ierr+1
	lda nmiv 	; restore-vektor merken
	sta ju3+1
	lda nmiv+1
	sta ju3+2
	lda #51 	; rom abschalten
	sta port
	ldy #0
modi	lda vic,y 	; zeichensatz anlegen
	sta vic,y
	lda vic+$100,y
	sta vic+$100,y
	lda #119
	sta 55296,y 	; farben setzen
	sta 55552,y
	sta 55808,y
	sta 56064,y
	lda #32
	sta 54272,y 	; geister-bildschirm
	sta 54528,y 	; loeschen
	sta 54784,y
	sta 55040,y
	iny
	bne modi
point	tya 	; sprite-pointer
	clc 	; fuer betrieb setzen
	adc #72 	; auf 72,73,...
	sta 55288,y 	; = daten ab $d200
	iny
	cpy #8
	bcc point
	ldy #35
hlp1	lda help1,y 	; bedienungsanleitung teil 1
	sta 54554,y
	dey
	bpl hlp1
	ldy #24
hlp2	lda help2,y 	; und teil 2
	sta 54600,y 	; in geister-schirm schreiben
	dey
	bpl hlp2
	iny
	ldx #48
numb	txa 	; ziffern 0..7 in
	sta 54434,y 	; geister-schirm schreiben
	iny
	iny
	iny 	; je 5 spaces
	iny
	iny
	inx
	cpx #56
	bcc numb
	lda #55 	; rom einschalten
	sta port
	lda #0 	; betrieb freigeben
	sta active
	lda #<hi 	; einschaltmeldung
	ldy #>hi
	jmp $ab1e 	; ausgeben (strout)
; **** neuer direktmodus-vektor
vec3	pha 	; akku retten
	lda #<vec1 	; neuen ausgabe-vektor
	sta ibsout 	; setzen
	lda #>vec1
	sta ibsout+1
	pla 	; akku zurueckholen
ju1	jmp 0 	; selbstmodifikation
; **** neuer ausgabe-vektor
vec1	pha 	; akku retten
	lda #<vec2
	sta nmiv 	; neuen restore-vektor
	lda #>vec2 	; (nmi-vektor)
	sta nmiv+1 	; setzen
	pla 	; akku zurueckholen
ju2	jmp 0 	; selbstmodifikation
; **** far-branches
qabort	jmp abort
qskip	jmp skip
; **** neuer restore-vektor
vec2	sei 	; irq sperren
	pha 	; akku retten
	bit active 	; wenn schon aktiv
	bmi qabort 	; dann abbruch
	sec
	ror active 	; betrieb sperren
	txa
	pha 	; x-reg. retten
	tya
	pha 	; y-reg. retten
	lda port
	pha 	; prozessorport retten
	lda #54 	; basic abschalten
	sta port
	lda #0
	sta tast
	tax
	tay
prell3	lda tast+1
	cmp tast+1 	; entprellen
	bne prell3
	cmp #$ff 	; taste gedrueckt
	bne qskip 	; dann abbruch
; **** warteschleife
wait	iny
	bne wait
	inx
	bne wait
	lda tmp
	pha 	; speicherzellen retten
	lda tmp+1
	pha
	lda tmp+2
	pha
	lda tmp+3
	pha
; **** sprite-definitionen kopieren
	lda bank 	; startadresse der
	eor #3 	; vic-bank berechnen
	asl
	asl
	asl
	asl 	; mal 64
	asl
	asl
	sta hiadr
	lda vic+24
	and #$f0
	lsr
	lsr
	clc
	adc hiadr 	; adresse der sprite-
	sta baadr 	; pointer berechnen
	lda #48 	; ram ein
	sta port
	ldy #0 	; anfangen beim ersten sprite
	sty mobnr
	sty mobadr
	lda #>mobmem
	sta mobadr+1
moremob	ldy #0
	sty tmp+1
	lda #$f8 	; lowbyte des sprite-pointers
	sta tmp+2
	lda baadr
	clc
	adc #3 	; highbyte
	sta tmp+3
	ldy mobnr
	lda (tmp+2),y 	; sprite-pointer lesen
	ldx #5
mal64	asl 	; mal 64 gibt adresse
	rol tmp+1
	dex
	bpl mal64
	sta tmp
	clc
	lda tmp+1
	adc hiadr
	sta tmp+1
; **** 64 sprite-daten kopieren
	ldy #63
	lda mobadr
	sta tmp+2
	lda mobadr+1
	sta tmp+3
cop2	lda (tmp),y 	; aus sprite-bereich
	sta (tmp+2),y 	; in geister-bereich
	dey
	bpl cop2
	lda mobadr
	clc
	adc #64 	; plus 64, gibt naechste
	sta mobadr 	; geisteradresse
	bcc noinc
	inc mobadr+1
noinc	inc mobnr 	; naechstes sprite
	lda mobnr
	cmp #8 	; schon 8 sprites
	bne moremob 	; nein, weiter
	lda #54 	; ram/kernal ein
	sta port
	ldy #46 	; sicherheitskopie der 46
incopy	lda vic,y 	; vic-register anlegen
	sta vicmem,y
	dey
	bpl incopy
	lda #27 	; textmodus ein
	sta vic+17
	lda #8 	; normalen darstellungsmodus
	sta vic+22
	ldy #0 	; sprites nicht expandieren
	sty vic+23
	sty vic+29
	lda #84 	; zeiger auf geisterbildschirm
	sta vic+24
	lda bank
	pha 	; bank retten
	and #$fc 	; bank 3 einschalten
	sta bank
	ldy #16
setcoord	lda coord,y
	sta vic,y 	; sprite-koordinaten setzen
	dey 	; fuer alle acht sprites
	bpl setcoord
	jsr fram 	; farbram retten
; **** auf tastendruck sprites abschalten
menue	ldx #0
nokey	lda tt1,x 	; tastatur auslesen
	sta tast
prell1	lda tast+1
	cmp tast+1 	; entprellen
	bne prell1
	cmp tt2,x 	; x = nummer der taste
	beq ok
	inx
	cpx #9 	; alle 9 tasten geprueft
	bcc nokey 	; nein, weiter
ok	cpx #8 	; return-taste
	beq done 	; ja, fertig
	bcs menue 	; keine taste, weiter
; **** sprite nr. x loeschen
	lda nobit,x 	; aus tabelle zu loeschendes bit
	and vicmem+21 	; bit (2 hoch x) loeschen
	sta vicmem+21 	; sprite abschalten
	sta vic+21 	; sprite ausblenden
	jmp menue 	; weiter warten
; **** return-taste
done	jsr fram 	; farbram zurueckholen
	ldy #46 	; vic-register zurueckholen
recopy	lda vicmem,y
	sta vic,y
	dey
	bpl recopy
	pla 	; bank zurueckholen
	sta bank
	pla
	sta tmp+3 	; zwischenspeicher
	pla 	; zurueckholen
	sta tmp+2
	pla
	sta tmp+1
	pla
	sta tmp
	lda vic+30 	; kollisionsregister loeschen
	lda vic+31
	lda #143 	; vic-irq loeschen
	sta vic+25
	lda ciairq 	; cia-irq loeschen
; **** pause-funktion
	lda #0
	sta tast 	; tastatur lesen
prell2	lda tast+1
	cmp tast+1 	; entprellen
	bne prell2
	cmp #$ff 	; wenn taste noch gedrueckt
	bne prell2 	; dann weiter warten
skip	lda #$7f
	sta tast 	; tastatur-abfrage auf default
	pla
	sta port 	; prozessorport zurueckholen
	pla
	tay 	; y-reg. zurueckholen
	pla
	tax 	; x-reg. zurueckholen
	lsr active 	; betrieb wieder freigeben
abort	pla 	; akku zurueckholen
ju3	jmp 0 	; und fertig (s'modifikation)
; **** farbram retten/zurueckholen
fram	ldy #0
	sty tmp
	lda #216 	; farbram-adresse $d800
	sta tmp+1
cop1	lda (tmp),y 	; farbram lesen
	pha 	; wert merken
	lda #48 	; ram einschalten
	sta port
	lda (tmp),y 	; geister-wert lesen
	tax 	; farbram mit geister-bereich
	pla 	; vertauschen
	sta (tmp),y
	lda #54 	; farbram einschalten
	sta port
	txa
	sta (tmp),y
	iny 	; naechstes byte
	bne cop1
	inc tmp+1 	; naechste page
	ldx tmp+1
	cpx #220 	; schon bei $da00
	bne cop1 	; dann fertig
	rts
; **** bereich fuer variablen
vicmem	.byte "                                                "
; war speicher fuer vic-register
hiadr	brk 	; startadresse vic-bank
baadr	brk 	; startadresse bildschirm
mobnr	brk 	; spritenummer
mobadr	.word 0 	; spriteadresse
active	brk 	; flag restore-taste
; **** bereich fuer tabellen
nobit	.byt $fe,$fd,$fb,$f7,$ef,$df,$bf,$7f 	; tabelle geloeschter bits
coord	.byt $20,$3a,$48,$3a,$70,$3a,$98 	; sprite-koordinaten
	.byt $3a,$c0,$3a,$e8,$3a,$10,$3a,$38,$3a,$c0
tt1	.byt $ef,$7f,$7f,$fd,$fd,$fb,$fb,$f7,$fe 	; tastatur spalten
tt2	.byt $f7,$fe,$f7,$fe,$f7,$fe,$f7,$fe,$fd 	; tastatur zeilen
; **** ascii-texte
; 'mit zifferntasten sprites abschalten
help1	.byt 13,9,20,32,26,9,6,6,5,18,14,20,1,19,20,5,14
	.byt 32,19,16,18,9,20,5,19,32,1,2,19,3,8,1,12,20,5,14
; 'oder <return> wenn fertig
help2	.byt 15,4,5,18,32,60,18,5,20,21,18,14,62,32,23,5,14,14
	.byt 32,6,5,18,20,9,7
; einschaltmeldung
hi	.byt 13
	.byte "\x12restore\x92-taste"
	.byt 13,0
