;:sys36864
	;.opt oo
	*=$c800
;
; quelltext zu 'splines'
;
; von nikolaus heusler
; XXXXXXXXXXXX XX / XXXX XXXXXXXX XX
;
; 03.03.91 - 06.03.91
;
; *** variablen ***
;
tmp	=2	;zwischenspeicher
getkoord	=$b7eb	;koordinaten holen
xcoord	=20	;x-koordinate l/h
vic	=$d000	;videochip
bank	=56576	;vic-bank
getx	=$b7f1	;parameter holen
scrn	=$c400	;farbspeicher
graf	=$e000	;grafikspeicher
komma	=$aefd	;komma holen
av	=4	;zeiger in grafik
port	=1	;prozessorport
strout	=$ab1e	;text ausgeben
anz	=6	;anzahl punkte -1
yk	=820	;tabelle y-koord.
xl	=yk+8	;tabelle x-koord. lo
xh	=xl+8	;tabelle x-koord. hi
errout	=$a445	;fehlermeldung
errlo	=$22	;zeiger auf error
chrgot	=121	;letztes zeichen
syntax	=$af08	;syntax error
t	=704	;fliesspunkt-wert
tstep	=t+5	;schrittweite fuer t
memdiv	=$bb0f	;fac=mem/fac
fac	=$62	;fliesspunkt-akku
intflt	=$bc49	;fac=int
eins	=$bfe8	;flp-wert 1
facmem	=$bbd4	;mem=fac
ko	=tstep+5	;koordinate (flp)
i	=254	;punkt-nummer
flp	=ko+5	;fliesspunkt-wert
memmult	=$ba28	;fac=fac*mem
exp	=$61	;exponent vom fac
memarg	=$ba8c	;arg=mem
memfac	=$bba2	;fac=mem
facarg	=$bc0c	;arg=fac
memplus	=$b867	;fac=fac+mem
integer	=$bc9b	;int=fac
plus05	=$b849	;fac=fac+0.5
sgn	=$66	;vorzeichen vom fac
byt	=$64	;integerwert
y	=253	;y-koordinate
intg	=$b801	;int=fac
argfac	=$bbfc	;fac=arg
memmin	=$b850	;fac=mem-fac
mode	=252	;modusbyte m
hochz	=flp+5	;potenz
expo	=251	;exponent
mant	=hochz+5	;mantisse
cx	=249	;crsr-koordinate x lo/hi
cy	=248	;crsr-koordinate y
rst	=142	;rest fuer linie
gro	=139	;rundung fuer linie
yadd	=140	;fuer linie
xadd	=141	;fuer linie  lo/hi
dy	=247	;fuer linie
dx	=181	;fuer linie  lo/hi
x	=166	;x-koordinate lo/hi
first	=168	;flag erste linie
;
; *** sprungtabelle
;
	jmp info	;hilfsbildschirm
	jmp on	;grafik an
	jmp off	;grafik aus
	jmp clr	;grafik loeschen
	jmp set	;punkt setzen
	jmp spline	;(s)pline setzen
;
; *** anfang programm ***
;
on	jsr getx
	txa
	ldy #0
	sty tmp
	ldx #>scrn
	stx tmp+1
	ldx #4
colin	sta (tmp),y
	dey
	bne colin
	inc tmp+1
	dex
	bne colin
	lda #0
	sta bank
	lda #59
	sta vic+17
	lda #29
	sta vic+24
	rts
off	lda #3
	sta bank
	lda #21
	sta vic+24
	lda #27
	sta vic+17
	rts
clr	ldx #32
	lda #>graf
	sta tmp+1
	ldy #0
	sty tmp
	tya
gclr	sta (tmp),y
	dey
	bne gclr
	inc tmp+1
	dex
	bne gclr
	rts
set	jsr komma
	jsr getkoord
; * punkt in grafik setzen
plot	sei
	cpx #200
	bcs ill
	lda xcoord+1
	cmp #>320
	bcc drin
	bne ill
	lda xcoord
	cmp #<320
	bcc drin
ill	cli
	rts
drin	txa
	lsr
	lsr
	lsr
	asl
	tay
	lda mult+1,y
	sta av+1
	txa
	and #7
	clc
	adc mult,y
	sta av
	lda xcoord
	and #$f8
	adc av
	sta av
	lda av+1
	adc xcoord+1
	sta av+1
	lda xcoord
	and #7
	tax
	lda grbit,x
	ldx #48
	stx port
	ldy #0
	ora (av),y
	sta (av),y
	lda #55
	sta port
	cli
	rts
info	lda #<help
	ldy #>help
	jmp strout
spline	jsr getx
	stx tstep
	jsr getx
	stx mode
	ldx #-1
	stx anz
	inx
	stx first
loop1	jsr chrgot
	beq fini
	cmp #","
	beq isko
	jmp syntax
isko	inc anz
	jsr komma
	jsr getkoord
	ldy anz
	txa
	sta yk,y
	lda xcoord
	sta xl,y
	lda xcoord+1
	sta xh,y
	jmp loop1
fini	lda anz
	cmp #1
	bcs ueber1
points	lda #<error
	sta errlo
	lda #>error
	jmp errout
ueber1	cmp #8
	bcs points
	sbc #0
	asl
	asl
	asl
	adc #<perm
	sta load+1
	lda #>perm
	adc #0
	sta load+2
	lda mode
	and #1
	beq nodraw
	jsr draw
nodraw	lda mode
	and #4
	beq spli
	jsr pline
spli	lda mode
	and #2
	bne spliok
	rts
spliok	lda tstep
	beq points
	jsr intfac
	lda #<eins
	ldy #>eins
	jsr memdiv
	ldx #<tstep
	ldy #>tstep
	jsr facmem
	lda #0
	ldx #4
clrt	sta t,x
	dex
	bpl clrt
; * einen punkt der spline plotten
loop2	lda #0
	ldx #4
	sta i
clrko1	sta ko,x
	dex
	bpl clrko1
loop3	ldy i
	lda yk,y
	ldx #0
	jsr sub
	lda #<ko
	ldy #>ko
	jsr memplus
	ldx #<ko
	ldy #>ko
	jsr facmem
	inc i
	lda i
	cmp anz
	beq loop3
	bcc loop3
	lda #<ko
	ldy #>ko
	jsr memfac
	jsr plus05
	lda exp
	cmp #$89
	bcs nopoint
	lda sgn
	bmi nopoint
	jsr integer
	lda byt+1
	sta y
; * x-koordinate des pktes. berechnen
	lda #0
	ldx #4
	sta i
clrko2	sta ko,x
	dex
	bpl clrko2
loop4	ldy i
	lda xl,y
	ldx xh,y
	jsr sub
	lda #<ko
	ldy #>ko
	jsr memplus
	ldx #<ko
	ldy #>ko
	jsr facmem
	inc i
	lda i
	cmp anz
	beq loop4
	bcc loop4
	lda #<ko
	ldy #>ko
	jsr memfac
	jsr plus05
	lda exp
	cmp #$8a
	bcs nopoint
	lda sgn
	bmi nopoint
	jsr intg
	ldx y
	lda mode
	and #8
	bne zlines
	jsr plot
	jmp nopoint
zlines	lda first
	beq jungfrau
	lda xcoord
	sta x
	lda xcoord+1
	sta x+1
	jsr line
	jmp nopoint
jungfrau	lda xcoord
	sta cx
	lda xcoord+1
	sta cx+1
	lda y
	sta cy
	inc first
nopoint	lda #<t
	ldy #>t
	jsr memfac
	lda #<tstep
	ldy #>tstep
	jsr memplus
	ldx #<t
	ldy #>t
	jsr facmem
	lda t
	cmp #$81
	bcs hats
	jmp loop2
hats	rts
; * wandlung byte/word -> fac
intfac	ldx #0
worfac	sta fac+1
	stx fac
	ldx #$90
	sec
	jmp intflt
; * endpunkte der (s)pline zeichnen
draw	lda #0
	sta i
loopa	ldy i
	ldx yk,y
	stx y
	lda xl,y
	sta xcoord
	lda xh,y
	sta xcoord+1
	jsr plot
	inc xcoord
	bne noinc
	inc xcoord+1
noinc	jsr coplot
	inc y
	jsr coplot
	lda xcoord
	bne nodec
	dec xcoord+1
nodec	dec xcoord
	jsr coplot
	inc i
	lda i
	cmp anz
	bcc loopa
	beq loopa
	rts
coplot	ldx y
	jmp plot
; * unterprogramm
; berechnet teil der summe ueber i=0..n
; fuer die spline-koordinaten
sub	sta tmp
	stx tmp+1
; selbstmodifikation
load	lda load,y
	jsr intfac
	jsr fac3
	lda #<t
	ldy #>t
	jsr memfac
	lda i
	jsr hoch
	jsr mal3
	jsr fac3
	lda #<t
	ldy #>t
	jsr memfac
	lda #<eins
	ldy #>eins
	jsr memmin
	lda anz
	sec
	sbc i
	jsr hoch
	jsr mal3
	jsr fac3
	lda tmp
	ldx tmp+1
	jsr worfac
	jmp mal3
fac3	ldx #<flp
	ldy #>flp
	jmp facmem
mal3	lda #<flp
	ldy #>flp
	jmp memmult
; * potenzierung durch multiplikation ersetzen
hoch	beq one
	jmp potenz
one	lda #<eins
	ldy #>eins
	jmp memfac
potenz	sta expo
	ldx #<mant
	ldy #>mant
	jsr facmem
hoch1	ldx #<hochz
	ldy #>hochz
	jsr facmem
	dec expo
	bne hoch2
	rts
hoch2	lda #<mant
	ldy #>mant
	jsr memfac
	lda #<hochz
	ldy #>hochz
	jsr memmult
	jmp hoch1
pline	lda yk
	sta cy
	lda xl
	sta cx
	lda xh
	sta cx+1
	lda #0
	sta i
p1	inc i
	ldx i
	lda yk,x
	sta y
	lda xl,x
	sta x
	lda xh,x
	sta x+1
	jsr line
	lda i
	cmp anz
	bcc p1
	rts
; * linie zwischen x/y und cx/cy
line	lda #1
	sta yadd
	sta xadd
	lda x+1
	cmp cx+1
	bcc li1
	bne li2
	lda x
	cmp cx
	beq li3
	bcs li2
li1	lda #-1
	sta xadd
li2	lda #-1
	.byt $2c
li3	lda #0
	sta rst
	sta rst+1
	lda y
	cmp cy
	bcs li4
	ldx #-1
	stx yadd
li4	sec
	sbc cy
	sta dy
	ldx yadd
	bpl li4a
	eor #-1
	clc
	adc #1
	sta dy
li4a	lda x
	sec
	sbc cx
	sta dx
	lda x+1
	sbc cx+1
	sta dx+1
	lda xadd
	bpl li4b
	lda #0
	sec
	sbc dx
	sta dx
	lda #0
	sbc dx+1
	sta dx+1
li4b	lda dx+1
	bne li5
	lda dy
	cmp dx
	bcc li5
	lda #0
	.byt $2c
li5	lda #1
	sta gro
li6	ldx cy
	lda cx
	sta xcoord
	lda cx+1
	sta xcoord+1
	jsr plot
li9	lda cy
	cmp y
	bne li7
	lda cx
	cmp x
	bne li7
	rts
li7	lda rst
	ldx rst+1
	bmi li8
	sec
	sbc dx
	sta rst
	txa
	sbc dx+1
	sta rst+1
	lda cy
	clc
	adc yadd
	sta cy
	lda gro
	bne lie
	beq li6
li8	clc
	adc dy
	sta rst
	bcc li8a
	inc rst+1
li8a	lda xadd
	bmi lia
	inc cx
	bne lib
	inc cx+1
lib	jmp lic
lia	lda cx
	bne lid
	dec cx+1
lid	dec cx
lic	lda gro
	beq lie
	bne li6
lie	lda mode
	and #16
	bne li6
	beq li9
;
; *** variablen und konstanten ***
;
; multiplikationstabelle y=$e000+x*320
grbit	.byt $80,$40,$20,$10,8,4,2,1
mult	=*
	.word $e000,$e140,$e280,$e3c0
	.word $e500,$e640,$e780,$e8c0
	.word $ea00,$eb40,$ec80,$edc0
	.word $ef00,$f040,$f180,$f2c0
	.word $f400,$f540,$f680,$f7c0
	.word $f900,$fa40,$fb80,$fcc0
	.word $fe00
; tabelle mit permutationen
; 'i aus n'
; zeile = n   spalte = i
perm	=*
	.byt 1, 1, 0, 0, 0, 0, 0, 0 	; 1
	.byt 1, 2, 1, 0, 0, 0, 0, 0 	; 2
	.byt 1, 3, 3, 1, 0, 0, 0, 0 	; 3
	.byt 1, 4, 6, 4, 1, 0, 0, 0 	; 4
	.byt 1, 5,10,10, 5, 1, 0, 0 	; 5
	.byt 1, 6,15,20,15, 6, 1, 0 	; 6
	.byt 1, 7,21,35,35,21, 7, 1 	; 7
help	.byt 13
	.byte "\x0eSPLINES V1.0  by N. Heusler\x11"
	.byt 13
	.byte "(c) nh-040391-arr\x11"
	.byt 13
	.byte "SYS 51200      Help"
	.byt 13
	.byte "SYS 51203,C    Graphics on"
	.byt 13
	.byte "SYS 51206      Graphics off"
	.byt 13
	.byte "SYS 51209      Graphics clear"
	.byt 13
	.byte "SYS 51212,X,Y  Plot"
	.byt 13
	.byte "SYS 51215,...  Spline"
	.byt 13,0
error	.byte "number of pointS"
