;**************************************************************************
;
; Filename : UHR.ASM
; ------------------
;
; (c) 1990 by Thomas Lehmann
;
;
; Jackophone V5.00
;
;
; Uhrzeit ermitteln und ausgeben
;
;**************************************************************************



; =========================================================================
;
; Type	: Hauptprg.
;	: Uhr nachtriggern
;
;	: der Uhrbuffer hat folgenden Aufbau:
;	: -----------------------------------
;	: Wochentag, Jahr, Monat, Tag, Stunde, Minute, Sekunde
;
;
; Eingang	: wird von Hauptprogrammschleife aufgerufen
;
; Ausgang	: Uhrzeit und Datum wenn Sekunde erreicht weiterschalten
;
; Register	: Accu, X, Y
;
; (c) by Thomas Lehmann Feb. 1990
;
; =========================================================================

WTAG	.equ	0	; Position des Wochentags im Buffer
JAHR	.equ	1	; dito, Jahr
MON	.equ	2	; dito, Monat
TAG	.equ	3	; dito, Tag
STD	.equ	4	; dito, Stunde
MIN	.equ	5	; dito, Minute
SEK	.equ	6	; dito, Sekunde


uhr_trigger	lda sekunde	; Sekunde erreicht ?
	and #%00111111	; BIT`s für Uhrstatus ausblenden
	beq uhr_end	; nein, Uhr nicht nachtriggern

	bbs 6,sekunde,uhr_inc_01 ; Umschaltung bereits erfolgt
	jsr sw_umsch	; Sommer/Winterzeit Umschaltung testen

uhr_inc_01	rmb 7,sekunde	; Uhr neu ausgeben
	dec sekunde	; anstehende Sekunden-1
	ldx #UHR_BULA-1	; Offset auf Uhrbuffer laden, (Sekunde)
	inc uhr_buff,x	; Sekunde+1

uhr_inc	lda uhr_buff,x	; aktuellen Wert laden
	cmp uhr_tab_e,x	; Endwert erreicht ?
	bcs uhr_ueberl	; ja, Überlauf

	dex		; alle Werte getestet ?
	bpl uhr_inc	; nein

uhr_end	rts


	; Endwert eines Uhrwertes erreicht
	; --------------------------------
	; Wochentag, Jahr, Monat, Tag, Stunde, Minute, Sekunde

uhr_ueberl	cpx #STD	; überlauf Stunde ?
	bne uhr_u_1	; nein
	inc uhr_buff+WTAG	; Wochentag nachführen

uhr_u_1	cpx #TAG	; Überlauf Tag ?
	bne uhr_u_2	; nein

	ldy uhr_buff+MON	; Monat laden
	dey		; Offset auf Tage/Monat Tabelle
	cmp tag_mon_tab,y	; Ist Tag im Monat erreicht ?
	bcc uhr_u_2	; nein

	tay		; Tag merken
	lda uhr_buff+MON	; Monat laden
	cmp #02		; ist es Februar ?
	bne uhr_u_2	; nein

	lda uhr_buff+JAHR	; Jahr laden
	beq uhr_u_3	; es ist ein Jahrhundert ?

	and #$03	; ist es ein Schaltjahr ?
	bne uhr_u_2	; nein

uhr_u_3	cpy #30		; Februar hat 29 Tage im Schaltjahr
	bcs uhr_u_2	; Tag nicht zugelassen

	dex		; nächsten Wert einstellen
	bra uhr_inc	; Tag ist erlaubt

uhr_u_2	cpx #MON	; Überlauf Monat ?
	bne uhr_u_4	; nein

	rmb 6,sekunde	; Sommer/Winterzeit wieder testen
uhr_u_4	lda uhr_tab_a,x	; Startwert laden
	sta uhr_buff,x	; und neu starten
	dex		; nächsten Wert einstellen
	beq uhr_end	; alle Werte getestet, Ende
	inc uhr_buff,x	; Wert nachführen
	bra uhr_inc


	; ==================
	; Startwerte der Uhr
	; ==================

uhr_tab_a	.byte 0		; Start-Wochentag
	.byte 0		; Start-Jahr
	.byte 1		; Start-Monat
	.byte 1		; Start-Tag
	.byte 0		; Start-Stunde
	.byte 0		; Start-Minute
	.byte 0		; Start-Sekunde


	; ================
	; Endwerte der Uhr
	; ================

uhr_tab_e	.byte 7		; End-Wochentag
	.byte 100	; End-Jahr
	.byte 13	; End-Monat
	.byte 29	; End-Tag
	.byte 24	; End-Stunde
	.byte 60	; End-Minute
	.byte 60	; End-Sekunde


	; =====================
	; Anzahl der Tage/Monat
	; =====================

tag_mon_tab	.byte 32	; Januar
	.byte 29	; Februar 28 Tage, Schaltjahr = 29 Tage
	.byte 32	; März
	.byte 31	; April
	.byte 32	; Mai
	.byte 31	; Juni
	.byte 32	; Juli
	.byte 32	; August
	.byte 31	; September
	.byte 32	; Oktober
	.byte 31	; November
	.byte 32	; Dezember



; =========================================================================
;
; Type	: Hauptprg.
;	: Sommer/Winterzeit Umschaltung testen
;
; Eingang	: jede Sekunde
;
; Ausgang	: Sommer bzw. Winterzeit eingestellt wenn erforderlich
;
; Register	: Accu, X, Y
;
; (c) by Thomas Lehmann Feb. 1990
;
; =========================================================================

sw_umsch	lda uhr_buff+WTAG	; Wochentag laden, ist es Sonntag ?
	bne sw_end	; nein

	ldx uhr_buff+MON	; Monat laden
	dex		; Offset auf Tage/Monat Tabelle
	lda tag_mon_tab,x	; letzten Tag im Monat laden
	sec
	sbc #8		; Woche abziehen
	cmp uhr_buff+TAG	; ist es der letzte Sonntag im Monat ?
	bcs sw_end	; nein

	ldx #02		; Offset auf Sommer/Winter Tabelle
	ldy #UHR_BULA-1	; Offset auf Uhrbuffer laden, (Sekunde)

sw_loop	lda sw_tab,x	; Zeit der Umschaltung
	cmp uhr_buff,y	; ist Zeit erreicht ?
	bne sw_end	; nein
	dey		; nächsten Wert einstellen
	dex
	bpl sw_loop	; nächsten Wert testen

	lda uhr_buff+MON	; aktuellen Monat laden
	cmp #03		; ist es März ?
	bne winter	; nein, Winterumschaltung testen

	inc uhr_buff+STD	; Stunde +1, Sommerzeit
	bra sw_1

winter	cmp #09		; ist es September ?
	bne sw_end	; nein, keine Umschaltung

	dec uhr_buff+STD	; Stunde -1, Winterzeit
sw_1	smb 6,sekunde	; Sommer/Winter erst bei nächsten Monat testen
sw_end	rts

sw_tab	.byte 01,59,59	; Zeit der Umschaltung, Std., Min, Sek.


; =========================================================================
;
; Type	: Hauptprg.
;	: Uhr anzeigen
;
; Eingang	: -------
;
; Ausgang	: Uhrzeit, Datum und Schlüsselschalter im Display angezeigt
;
; Register	: Accu, X, Y
;
; (c) by Thomas Lehmann Feb. 1990
;
; =========================================================================

put_uhr	bbs 7,sekunde,p_u_end	; Uhrzeit wurde bereits ausgegeben

	; erreichten Termin ausgeben ?
	; ----------------------------
	lda err_term	; ist ein Termin erreicht ?
	beq put_uhr_1	; nein, Uhr ausgeben

	jmp put_errterm	; erreichten Termin ausgeben

put_uhr_1	smb 7,sekunde	; Uhrzeit ausgegeben eintragen
	jsr dpclr_cuoff	; Display löschen, Cursor aus

	; Uhr ausgeben
	; ------------
	lda uhr_buff+WTAG	; Wochentag laden
	asl		; Offset auf Tabelle erzeugen
	tax
	lda wtg_tab,x	; 1.Zeichen laden
	jsr putchar	; und ausgeben
	lda wtg_tab+1,x	; 2.Zeichen laden
	jsr putchar_sp	; ausgeben, SPACE hinterher

	ldy #UHR_BULA-2	; Offset auf Uhrbuffer laden

	.block
loop	lda format_tab,y	; Uhr im richtigem Format ausgeben
	tax		; aktuelles Zeichen laden
	lda uhr_buff,x	; Uhr-Wert laden
	jsr hextodez	; Hexwert nach dezimal wandeln
	jsr putzahl	; und dezimal ausgeben
	lda trnz_tab,y	; Trennzeichen laden
	jsr putchar	; und ausgeben
	dey		; alle Zeichen ausgegeben ?
	bpl loop	; nein
	.bend

	jsr put_ss	; Zustand des SS ausgeben
p_u_end	rts


wtg_tab	.text "SoMoDiMiDoFrSa"	; Wochentage


	; Aufbau der Uhranzeige
	; ---------------------
	; Wochentag, Tag, Monat, Jahr, Stunde, Minute, Sekunde
	; "Fr 13.02.90 23:24:49"

	; der Uhrbuffer hat folgenden Aufbau:
	; -----------------------------------
	; Wochentag, Jahr, Monat, Tag, Stunde, Minute, Sekunde

format_tab	.byte SEK,MIN,STD,JAHR,MON,TAG ; Ausg. Format der Uhr, rückwerts !

trnz_tab	.text " :: .."	; Trennzeichen


; =========================================================================
;
; Type	: Hauptprg.
;
; Eingang	: bei Taste "Uhr stellen"
;	: Offset auf Tastaturtabelle in X-Reg.
;	: Tastenwert im Accu
;
; Ausgang	: Text ausgegeben, Wähltasten umgeleitet
;
; Register	: X
;
; (c) by Thomas Lehmann Feb. 1990
;
; =========================================================================

key_uhr	jsr key_ende	; Ende-Taste ausführen

	lda #LD_L|LD_ON	; LED-Wert laden
	jsr set_led	; und LED einschalten

	ldx #WTA_UHRST	; Prg. Nr. bei Wähltaste
	stx wta_prg	; einschalten

	ldx #6		; Anzahl der Eingaben
	stx anz_input	; setzen
	ldx #UHR_BULA-1	; Offset auf Sekunde laden
	stx uhr_timdat	; und eintragen

	stz input_po	; keine Zeichen im Input-Buffer
	ldx #TXT_USTTIME	; Textnr. laden
	jmp puttxt	; und Text ausgeben


; =========================================================================
;
; Type	: Hauptprg.
;
; Eingang	: bei Wähltaste und eingeschaltetem "Uhr stellen" Modus
;	: Tastenwert im Accu
;
; Ausgang	: Uhr entsprechend der Eingabe gestellt
;
; Register	: Accu, X, Y
;
; (c) by Thomas Lehmann Feb. 1990
;
; =========================================================================

wta_uhrst	cmp #UHRST_END	; Uhr stellen verlassen ?
	beq uhrst_off	; ja, Modus ausschalten

	ldx input_po	; Offset auf akt. Eingabe
	cpx anz_input	; läuft "aendern ja/nein" Abfrage ?
	bcs wta_uhrst_2	; ja

	jsr check_wta	; Taste im Gültigkeitsbereich ?
	bcs wta_uhr_end	; nein, Ende

	jsr input	; Tastenwert eintragen
	inx		; Offset auf akt. Eingabe
	cpx anz_input	; Uhrwert komplett eingegeben ?
	bcc wta_uhr_end	; nein, noch nicht ändern abfragen

	ldx #TXT_AENDJN	; Textnr. laden, "aendern ja/nein"
	jmp puttxt	; Text ins Display

wta_uhr_end	rts


	; eingegebenen Uhrwert eintragen
	; Wochentag, Jahr, Monat, Tag, Stunde, Minute, Sekunde
	; ----------------------------------------------------

wta_uhrst_2	cmp #2		; ändern (Wtaste "2") ?
	beq wta_uhrst_3	; nicht ändern
	bcs wta_uhr_end	; ungültige Taste

	rmb 6,sekunde	; Zeit geändert, Sommer/Winter wieder testen
	ldy uhr_timdat	; Offset auf Uhreintrag laden
	lda input_po	; Pointer auf nächstes Zeichen im Buffer
	lsr		; 2 Byte Einträge
	tax
	dex		; auf letzte Eingabe stellen

get_uhrval	jsr get_input	; Wert aus Inputbuffer holen
	sta uhr_buff,y	; Uhrwert speichern
	lda uhr_timdat	; wird Zeit eingetragen ?
	bne get_uval_1	; ja
	iny		; Datum wird von 0-TAG eingetragen
	iny

get_uval_1	dey		
	dex		; alle Eingaben eingetragen ?
	bpl get_uhrval	; nein, nächsten Uhrwert eintragen

wta_uhrst_3	lda uhr_timdat	; Offset auf Uhrbuffer laden
	bne wta_uhrst_4	; Zeit wurde eingestellt, Datum setzen

uhrst_off	jmp key_ende	; Ende-Taste ausführen

wta_uhrst_4	stz uhr_timdat	; Datum stellen eintragen
	stz input_po	; Eingabe neu starten
	lda #8		; Anzahl der Eingaben
	sta anz_input	; und setzen
	ldx #TXT_USTDATE	; Textnr. laden
	jmp puttxt	; und Text ausgeben


usttime_txt	.shift "Uhrzeit (HHMMSS): "
ustdate_txt	.shift "Datum(TTMMJJWW):"






