;:sys36864
	;.opt oo
	*= 49152	;startadresse
;
;mit dieser routine in betrieb greift der c 64 bei verwendung
;der reservierten varibalen ti und ti$ nicht mehr auf den
;system-irq zu, sondern auf die genauere echtzeituhr der
;cia nr. 1 ($dc00)
;
;nikolaus heusler, XXXXXXXXXXXX XX, XXXX XXXXXXXX XX
;
ido	=$308	;vektor basicbefehl ausfuehren
chrget	=$73	;naechstes basic-zeichen holen
chrgot	=$79	;letztes basic-zeichen holen
strout	=$ab1e	;text ausgeben
error	=42053	;fehlermeldung ausgeben
errlo	=$22	;lowbyte fehlermeldung
ptr	=122	;basic-zeiger
tlet	=$88	;token fuer 'let'
oldbef	=$a7e4	;alten befehl ausfuehren
testletter	=$b113	;auf buchstabe pruefen
pruef	=$aeff	;prueft auf code in basictext
syntax	=$af08	;syntax error
frmevl	=$ad9e	;beliebigen ausdruck holen
frestr	=$b6a3	;holt string-parameter
str	=$22	;string-adresse
cia	=$dc00	;cia-basis cia nr.1
inter	=$a7ae	;interpreterschleife
tis	=$b2	;token fuer '='
ndo	=$30a	;vektor funktion (term) auswerten
oldorg	=$ae86	;normalen term auswerten
typ	=$d	;typflag (0=numerisch)
strs	=$b46f	;string an variable
puffer	=255	;zahlenumwandlungsbereich
fac	=$62	;fliesspunkt-akkumulator
intfac	=$bc49	;fac nach integer wandeln
fac10	=$bae2	;fac=fac*10
plus	=$baed	;fac=fac+arg
facarg	=$bc0c	;arg=fac
plusa	=$bd7e	;fac=fac+a
ctr	=$71	;stellenzaehler
pmem	=247	;latch basic-pointer
fmem	=249	;dito
tmp	=155	;zwischenspeicher
akku3	=$57	;zwischenspeicher fuer fac
memadd	=$b867	;fac=fac+speicher
memmult	=$ba28	;fac=fac*speicher
facakku3	=$bbca	;fac zwischenspeichern
afac	=$bc3c	;fac=akku
;routine installieren
	lda #<neubef
	ldy #>neubef
	sta ido
	sty ido+1	;befehlsvektor verbiegen
	lda #<neuorg
	ldy #>neuorg
	sta ndo
	sty ndo+1	;funktionen-vektor verbiegen
	lda #<hi
	ldy #>hi
	jmp strout	;einschaltmeldung ausgeben
;neuen basicbefehl ausfuehren
neubef	lda ptr
	sta pmem
	lda ptr+1
	sta pmem+1	;pointer merken
	jsr chrget	;naechstes zeichen holen
	cmp #tlet	;let testen
	beq islet
	cmp #$80
	bcc islet2	;let ausfuehren
;war keine let-zuweisung
old	lda pmem
	sta ptr
	lda pmem+1
	sta ptr+1	;pointer zurueckholen
	jmp oldbef	;alten befehl ausfuehren
;let-token erkannt
islet	jsr chrget	;variablenname holen
islet2	cmp #"t"	;erstes zeichen von ti($)
	bne old
	jsr chrget	;zweites zeichen
	cmp #"i"	;zweites zeichen von ti($)
	bne old
;ti gefunden, rest des var.namens ueberlesen
skip	jsr chrget
	bcc skip	;ziffer
	jsr testletter	;buchstabe testen
	bcs skip	;ja, dann ueberspringen
	cmp #"%"	;ti%
	beq old	;zuweisung an ti% normal behandeln
	cmp #"$"	;ti$
	beq settime
;zuweisung an ti nicht erlaubt (vgl. basic $b134)
	ldy #<cant1
	lda #>cant1	;zeiger auf fehlermeldung
;neue fehlermeldung ausgeben
err	sty errlo	;lowbyte erfassen
	jmp error	;und ausgeben
settime	jsr chrget
	cmp #tis
	beq stimmt	;istgleichzeichen testen
	jmp syntax	;syntax error
;zuweisung ti$= erkannt
stimmt	jsr chrget
	jsr frmevl	;term
	jsr frestr	;string holen und auswerten
	cmp #6	;string laenge
	beq sechs	;wenn sechs zeichen, dann ok
ill	ldy #<cant2
	lda #>cant2
	bne err	;sonst fehlermeldung
sechs	lda cia+$e	;steuerreg. 1
	ora #128
	sta cia+$e	;uhr auf 50 hz schalten
	lda cia+$f	;steuerreg. 2
	and #127	;bit 7 loeschen
	sta cia+$f	;uhrzeit setzen
	ldy #0	;zeiger auf string
	lda (str),y	;std-zehner
	sec
	sbc #"0"	;nach hex
	cmp #3
	bcs ill	;ueber 30 uhr
	asl
	asl
	asl
	asl	;*16
	sta tmp
	iny
	lda (str),y	;std-einer
	sec
	sbc #"0"	;nach hex
	cmp #10
	bcs ill	;einerstelle ueber 10
	ora tmp	;mit zehner verknuepfen
;umrechnung ins 24 stunden format
	bne notnull	;nicht null uhr
	lda #$92	;%10000000+$12 = 12 uhr pm
	bne setstd
notnull	cmp #$24
	bcs ill	;ueber 24 uhr
	cmp #$13
	bcc setstd	;vormittag
	php
	sec
	sei
	sed
	sbc #$12
	plp
	ora #$80	;pm-flag
setstd	sta cia+$b	;stunden setzen, uhr anhalten
	jsr get59	;minuten holen
	sta cia+$a	;setzen
	jsr get59	;sekunden holen
	sta cia+9	;setzen
	lda #0
	sta cia+8	;uhr hochfahren (1/10 sekunde)
;uhr gesetzt, fertig
	jmp inter	;zurueck in die interpreterschleife
;parameter zwischen 0 und 59 holen und wandeln -> bcd
get59	iny
	lda (str),y	;zeichen holen
	sec
	sbc #"0"	;nach hex
	cmp #6
	bcs ill
	asl	;mal 2
	asl	;mal 4
	asl	;mal 8
	asl	;mal 16
	sta tmp
	iny	;naechstes zeichen
	lda (str),y
	sec
	sbc #"0"	;hex
	cmp #$a
	bcs ill
	ora tmp	;mit zehnerstelle verknuepfen
	rts	;gibt bcd-format
;term auswerten
neuorg	lda ptr
	sta fmem
	lda ptr+1
	sta fmem+1	;pointer merken
	lda #0
	sta typ	;typflag auf numerisch
	jsr chrget
	cmp #"t"	;erster buchstabe von ti($)
	beq isti
;war nicht ti oder ti$, also normal weiter
aint	lda fmem
	sta ptr
	lda fmem+1
	sta ptr+1
	jmp oldorg	;alte routine
isti	jsr chrget
	cmp #"i"	;zweiter
	bne aint	;zweites zeichen testen
;ti gefunden, rest des var.namens ueberlesen
jump	jsr chrget
	bcc jump	;ziffer
	jsr testletter	;buchstabe testen
	bcs jump	;ja, dann ueberspringen
	cmp #"%"	;ti%
	beq aint	;zuweisung von ti% normal behandeln
	cmp #"$"	;ti$
	beq strg
	jmp time	;ti
; zuweisung von ti$ an variable
strg	jsr klar	;in klartext wandeln
	jsr strs	;zu str$, string generieren
	jmp chrget	;weiter zur auswertung
;umrechnung bcd -> dezimal und in puffer
inbuf	pha
	and #$f0	;bits 4 mit 7 isolieren
	lsr
	lsr
	lsr
	lsr	;durch 16 teilen
	jsr buf1
	pla
	and #$f	;untere bits holen
;ziffer in string wandeln und abspeichern
buf1	ora #"0"	;textformat
	sta !puffer,y	;ab in den puffer
	iny
	rts
;konverter bcd -> fliesspunkt
push	pha
	lsr
	lsr
	lsr
	lsr
	and #15
	sta tmp
	pla
	and #15
	ora tmp	;hex-format
	sta fac+1
	lda #0
	sta fac	;zur umwandlung in fac schreiben
	ldx #144
	sec
	jmp intfac	;vgl. kernal $bdd1
; cia umrechnen in klartext
klar	lda cia+$b	;stunden
	cmp #$12	;nachmittag
	beq nulluhr
	cmp #$80
	bcc stdout
	and #$7f	;pm bit loeschen
	cmp #$12
	beq stdout
	php
	sei
	sed
	clc
	adc #$12
	plp
	.byt $2c
nulluhr	lda #0
stdout	ldy #0	;pufferzeiger
	jsr inbuf	;stunden in puffer
	lda cia+$a	;minute
	jsr inbuf	;in puffer
	lda cia+9	;sekunde
	jsr inbuf
	lda #0
	sta puffer+6	;endezeichen setzen
	lda cia+8	;uhr weiterlaufen lassen (1/10 sek lesen)
	rts
;zuweisung von ti an variable
time	jsr klar	;nach ti$ wandeln
	pha	;1/10 sek merken
	ldy #0
	sty $61
	sty $66	;fac nullen
;es werden die einzelnen stellen von ti$ nacheiander
;kaskadisch mit 30 multipliziert und gespeichert (vgl. basic $a9e7)
stelle	sty ctr	;stellenzaehler merken
	jsr getnext	;naechste ziffer holen plus fac
	jsr fac10	;fac=fac*10
	inc ctr
	ldy ctr
	jsr getnext	;naechste ziffer zu fac addieren
	jsr facarg	;fac nach arg kopieren
	tax	;exponent
	beq fac0	;fac=0
	inx	;exponent erhoehen = *2
	txa
	jsr plus	;fac=2*fac+arg entspricht *3
fac0	ldy ctr	;stellenzaehler
	iny
	cpy #6	;schon 6 stellen
	bcc stelle
;fac=10*fac+6*zehntelsekunden
	jsr fac10	;fac=fac*10
	jsr facakku3	;fac speichern
	pla	;1/10 sekunden
	jsr afac	;nach fac
	lda #<sex
	ldy #>sex
	jsr memmult	;fac=fac*6
	lda #<akku3
	ldy #>akku3
	jsr memadd	;fac=fac+merk
	jmp chrgot	;zurueck zur auswertung
getnext	lda !puffer,y	;zeichen aus puffer holen
	and #15	;nach hex wandeln
	jmp plusa	;fac=fac+a
;datenbereich einschaltmeldung
hi	.byt 13
	.byte "konvertierungsroutine ti$ -> cia"
	.byt 13
	.byte "version 1  02.91  installiert"
	.byt 13,13
	.byte "(c) nikolaus heusler"
	.byt 13
	.byte "    zwengauerweg  18"
	.byt 13
	.byte "    8000 muenchen 71"
	.byt 13,0
;fehlermeldungen
cant1	.byte "can't definE"
cant2	.byte "time formaT"
;fliesskommakonstanten
sex	.byt $83,$40,0,0,0	;fliesskommazahl 6
; ---- ende ----
