processor 6502 ;version 1.11 ;rds-dekoder fuer 6502 mikrocomp. ;der marke eigenbau ;(c)/(w)8/94,9/94 by Carsten Gross ;konstanten: org $e000 ; Variablen-definition ; ------------------------------------------------------------- via equ $2000 lcd equ $2800 ;konstanten des via-chips porta equ via+1 portb equ via drrb equ via+2 drra equ via+3 timer1l equ via+4 timer1h equ via+5 timer1ll equ via+6 timer1hl equ via+7 timer2l equ via+8 timer2h equ via+9 schiebereg equ via+10 acr equ via+11 pcr equ via+12 ifr equ via+13 ier equ via+14 portaoh equ via+15 ;konstanten fuer lcd-display steuerreg equ lcd datareg equ lcd+1 zpadd1 equ $02 memtop equ $0800 counter equ zpadd1+2 tastpuf equ counter+1 uhr equ tastpuf+1 ;ascii, 8 bytes dirtydispf equ uhr+8 ;0 display ok, 1=uhr, 2=unterer teil, 4=ps datum equ dirtydispf+1 ;ascii, 6 bytes datenzeile equ datum+8 ;was wird unten angezeigt? pi, pty, rt, af etc. rtvekt equ datenzeile+1 ;1byte scrollges equ rtvekt+1 ;1byte scrollf equ scrollges+1 ;1byte altpi equ scrollf+1 ;2byte ptypuf equ altpi+2 ;1byte tp equ ptypuf+1 ;1byte rdsdirty equ tp+1 ;1byte rdspuf equ rdsdirty+1 ;13byte null equ rdspuf pih equ rdspuf+1 pil equ rdspuf+2 eins equ rdspuf+3 ki equ rdspuf+4 po equ rdspuf+5 zwei equ rdspuf+6 byte1 equ rdspuf+7 byte2 equ rdspuf+8 drei equ rdspuf+9 byte3 equ rdspuf+10 byte4 equ rdspuf+11 rtpuf equ $200 ;128byte pspuf equ rtpuf+$80 ;8byte afpuf equ pspuf+$08 ;128by rdspufa equ rdspuf+13 ;13byte mjd equ rdspufa+13 ;1byte mjdunkorr equ mjd+3 ;3byte kzp1 equ mjdunkorr+3 ;2byte kzp2 equ kzp1+2 ;2byte tag equ kzp2+2 ;1byte monat equ tag+1 ;1byte jahr equ monat+1 ;1byte zw equ jahr+1 ;2byte mr equ zw+2 ;2byte kzp3 equ mr+2 ;2byte zeile2vekt equ kzp3+2 ;2byte asciipty equ afpuf+128 ;16byte asciidatum equ asciipty+$10 ;16by wochentag equ zeile2vekt+2 ;1byte datumdirty equ wochentag+1 ;1byte asciipi equ asciidatum+$10 ;16by asciiaf equ asciipi+$10 ;16byte di equ datumdirty+1 ;1byte musik equ di+1 ;1byte irqkzp equ musik+1 ;1byte irqcount2 equ irqkzp+1 ;1byte afvekt equ irqcount2+1 ;1by afplatz equ afvekt+1 ;1by sendtabf equ afplatz+1 ;1by afnummer equ sendtabf+1 ;3by afascpuf equ afnummer+3 ;3by afdirty equ afascpuf+4 ;1by startwertmjd equ 35002 datacount equ afascpuf+1 ;1by dreibytepuf equ datacount+1 ;3by pufvekt equ dreibytepuf+3 ;1by asciivf equ asciiaf+$10 ;16by asciimusik equ asciivf+$10 ;16by asciidi equ asciimusik+$10 ;16by ; ; Und los gehts mit Programmcode ; ---------------------------------------------------------------------- dc.b "SW V1.11 (C)OKT 94 CG " ; Reset-Routine ; reset sei cld ldx #$ff ;Stackpointer initialisieren txs ldy #$00 ;Stack mit 0 loeschen tya l1 sta $0100,y iny bne l1 l2 lda $0100,y ;Sind die Nullen auch "drin" bne sperror ;Nein? --> Speicherfehler iny bne l2 lda #$aa ;Test mit Bitmuster %10101010 l3 sta $0100,y iny bne l3 l4 lda $0100,y ;nicht im Stack? cmp #$aa ;= Fehler bne sperror iny bne l4 ;der stack ist getestet und kann ;genutzt werden! lda #$00 ;Zeropage loeschen l5 sta $00,y iny bne l5 ldx #$01 stx zpadd1+1 ;nun den Bereich von $0100-Ramende loeschen l6 sta (zpadd1),y iny bne l6 inc zpadd1+1 ldx zpadd1+1 cpx #>[memtop] bne l6 jsr konstsp ;Konstanten im Speicher ablegen jsr viainit ;VIA 6522 initalisieren jsr lcdinit ;LC-Display setzen jsr prompt ;Einschaltmeldung cli jmp hauptprg ;Und in die Systemwarteschleife ; Weiter in der Resetroutine ; ----------------------------------------------- sperror jmp sperror1 ;ab hier normale speicherloeschroutine wenn neues prg. neuerpi ldx #$80 ;Radiotext im Puffer loeschen lda #$20 l16 sta rtpuf-1,x dex bne l16 ldx #$09 l17 sta pspuf-1,x ;Programmname loeschen dex bne l17 txa l18 sta afpuf,x ;AF's loeschen inx cpx #$80 bne l18 sta rtvekt ;Start des Radiotextes wieder bei $00 sta musik sta ptypuf sta di ;und noch allerlei Bit's und Flags loeschen sta tp sta afvekt sta afplatz rts ;speicherfehler=>fehlerblinken! sperror1 lda #$07 ;Fehlerblinken bei Hardwareproblemen sta drrb lda portb errorbl eor #$07 sta portb ldx #$ff l22 dey bne l22 dex bne l22 jmp errorbl ; ; VIA 6522 initialisieren ; ------------------------------------------------------------- viainit lda #$00 ;Port A auf eingang sta drra lda #$07 ;Untere 3 leitungen Port B auf Ausgang sta drrb lda portb ;und auf 0 legen, also LED's aus and #$f8 sta portb lda #$3e ;Timer 1 auf 1/25 sec. sta timer1ll lda #$9c sta timer1hl ;Interrupt durch Timer1 sta timer1h lda #$c1 sta ier ;timer1 irq set, ca2 irq sta ifr ;IRQ im IER ermoeglichen lda #$00 ;Fallende flanke von ca2=irq sta pcr lda #$4c ;Timer1 free run, Schiebereg eingabe sta acr lda #$00 sta schiebereg ;Schieberegister start rts ; LC-Display initialisieren ; ---------------------------------------------- lcdinit ldx #$00 ;Tabellenwerte siehe Datenblatt zum LC-Display l9 lda lcdinittab,x jsr busychk sta steuerreg inx cpx #06 bne l9 lda #$40 ;Zeiger auf 1. Zeichen im Character RAM jsr busychk sta steuerreg ldx #$00 ;Neuen Zeichensatz g,ae,ue,oe laden l63 lda zeichens,x jsr busychk sta datareg inx cpx anzahlz bne l63 rts ;busycheck, testet ob LCD busy ;und wartet bis es bereit ist busychk pha l8 lda steuerreg bmi l8 pla rts ;einschaltmeldung fuer ;ca. 2 sekunden darstellen ; (gehoert eigentlich noch zur Resetroutine) prompt lda #$80 jsr busychk sta steuerreg ;Cursor auf Zeile 1 Spalte 1 ldx #$00 l11 lda promptz1,x ;Und 1.Zeile ausgeben beq l10 jsr busychk sta datareg inx bne l11 l10 lda #$c0 ;Cursor auf Zeile 2 Spalte 1 jsr busychk sta steuerreg ldx #$00 l13 lda promptz2,x ;und die 2. Zeile darstellen beq l12 jsr busychk sta datareg inx bne l13 l12 ldx #$ff ;"Busy-Waiting" ca. 2 Sekunden lda #$05 ;die Einschaltmeldung darstellen l14 dey bne l14 dex bne l14 sec sbc #$01 bne l14 lda #$01 jsr busychk ;und Display "Clear/Home" sta steuerreg lda #$07 ;gesammten Displayinhalt neu aufbauen sta dirtydispf rts ;Hauptprogramm und Systemwarte- ;schleife, wartet auf setzen der ;flaggen in den Jobpuffern und ;verzweigt entsprechend ; ---------------------------------------------------------------- hauptprg lda dirtydispf and #$01 beq l55 jsr uhrakt lda dirtydispf and #$fe sta dirtydispf l55 lda dirtydispf and #$04 beq l31 jsr psneu lda dirtydispf and #$fb sta dirtydispf l31 lda datumdirty and #$01 beq l56 jsr datumber jsr wochentber jsr wanddatum lda datumdirty and #$fe sta datumdirty l56 lda dirtydispf and #$02 beq l57 jsr zeile2neu lda dirtydispf and #$fd sta dirtydispf l57 lda rdsdirty beq l34 jsr rdsausw lda #$00 sta rdsdirty l34 lda afdirty bpl l120 lda #$00 sta afdirty jsr afwand lda datenzeile cmp #$04 bne l120 jsr zeile2neu l120 jmp hauptprg ; Und immer weiterschleifen ; ------------------------------------------------- ;berechnung des richtigen wochen ;tages aus mjd wochentber lda #$00 ;Zaehler loeschen sta zw sta zw+1 l84 clc lda zw adc #$07 ;7 Tage dazuaddieren sta zw lda zw+1 adc #$00 sta zw+1 lda zw ;Ist der Zaehler schon groesser als MJD? sec sbc mjd lda zw+1 sbc mjd+1 bcc l84 ;Nein, weiter addieren lda zw ;Sonst wieder eine Woche abziehen sbc #$07 sta zw lda zw+1 sbc #$00 sta zw+1 ;Und die Differenz als Zeiger auf sec ;den Wochentag benuetzen lda mjd sbc zw sta wochentag rts ;Uhr auf dem LC-Display ;darstellen uhrakt lda #$88 ;Cursor setzen auf Zeile 1, Spalte 9 jsr busychk sta steuerreg ldx #$00 l43 lda uhr,x jsr busychk sta datareg inx cpx #$08 bne l43 rts ;Programmname darstellen psneu lda #$80 ;Cursor setzen auf Zeile 1 Spalte 1 jsr busychk sta steuerreg ldx #$00 l44 lda pspuf,x jsr busychk sta datareg inx cpx #$08 bne l44 rts ;Informationen der zeile 2 ;darstellen. ; zeile2neu lda #$c0 ;Cursor setzen auf die 2. Zeile jsr busychk sta steuerreg ldx #$00 ldy rtvekt ;Wird nur fuer Scrolling genutzt sonst=0 l46 lda (zeile2vekt),y ;jeweiligen "dienst" darstellen jsr codewand ;umdefiniertes g und Umlaute bereitstellen jsr busychk sta datareg iny cpy scrollges ;Bei Ende des Scrolltextes wieder von vorne bne l72 ;anfangen ldy #$00 l72 inx cpx #$10 bne l46 rts ;codewandlung, und neuer zs codewand stx kzp2 ;Zeichen wandeln cmp #$67 bne l64 lda #$00 l64 cmp #$99 bne l65 lda #$f5 l65 cmp #$98 bne l66 lda #$ef l66 cmp #$97 bne l67 lda #$e1 l67 cmp #$9a bne l68 lda #$e2 l68 ldx kzp2 rts ;datum ins ascii-format wandeln wanddatum ldx #$00 ;Datumspuffer loeschen lda #$20 l49 sta asciidatum,x inx cpx #$10 bne l49 ;Wochentag holen lda wochentag and #$07 ;und als Zeiger auf Wochentagstabelle im asl ;ROM benutzen asl asl tax ldy #$00 ;ASCII Konstanten in Ausgabepuffer schreiben l51 lda wochttab,x beq l50 sta asciidatum,y inx iny cpy #$08 bne l51 l50 lda datum ;fuehrende Nullen unterdruecken cmp #$30 bne l52 lda #$20 l52 sta asciidatum,y iny lda datum+1 sta asciidatum,y ;Tag in ASCII-Ausgabepuffer geschrieben iny lda #"." ;Trennzeichen "punkt" sta asciidatum,y iny lda datum+2 ;Fuehrende Null unterdruecken cmp #$30 beq l53 sta asciidatum,y ;Monat steht iny l53 lda datum+3 sta asciidatum,y iny lda #"." ;Trennzeichen sta asciidatum,y iny lda datum+4 ;Jahr schreiben sta asciidatum,y iny lda datum+5 sta asciidatum,y ;Fertig iny rts ;Alternativfrequenz in tabelle ;eintragen afeintrag sta kzp1 ;Akku mit der AF merken ldx #$00 ;Tabelle auf Eintrag untersuchen l108 lda afpuf,x cmp kzp1 beq l107 cpx afplatz ;schon vorhanden --> Ende beq l109 inx cpx #$80 ;Tabellenende erreicht? bne l108 ;Nein, weitersuchen beq l107 ;ja, nicht eintragen l109 lda kzp1 ;Sonst normalen eintrag machen cmp #$cd ;Zu gross(>108Mhz) -> Ende bcs l107 sta afpuf,x ;Eintragen inc afplatz l107 rts ;pty-code auswerten ptywand lda ptypuf ;PTY-Code holen asl ;*16 asl ;=Tabellenzeiger asl asl tax ldy #$00 ;ASCII-Konstanten im ROM holen l61 lda ptytab,x sta asciipty,y ;und merken inx iny cpy #$10 bne l61 rts ;programmname und allerlei bit's ;merken! getps lda po ;VF-Durchsage flag holen and #$10 asl ;an die richtige Stelle schieben asl asl tax ;merken lda tp ;Durchsagekennung loeschen and #$7f sta tp txa ;und neue Kennung speichern als Bit 7 ora tp ;in "tp" sta tp lda po ;Zeiger auf Position im Stationsnamen holen and #$03 tax ;merken asl ;*2 tay ;nochmal merken lda sendtabf ;Wird gerade die Sendertabelle dargestellt? bne l143 ;ja, ende lda byte3 ;Sonst Stationsname im Puffer speichern sta pspuf,y lda byte4 sta pspuf+1,y l143 lda po ;Musik-Bit maskieren and #$08 lsr lsr lsr sta musik txa tay ;gemerkten Zeiger (PO and 3) holen lda po ;DI-Bit laden und maskieren and #$04 lsr lsr l78 cpx #$00 beq l77 asl dex bne l78 l77 ora di ;und abspeichern sta di ; eor hilfstab,y ; and di ; sta di lda tp ;Verkehrsduchsage im TP-Programm cmp #$81 ;ja-> LED an beq l83 lda portb ;sonst LED ausschalten (default) and #$fe sta portb jmp l105 l83 lda portb ora #$01 sta portb l105 lda ki ;Relikt ohne Funktion and #$08 ;beq l106 lda byte1 ;2 AF's in Tabelle eintragen jsr afeintrag lda byte2 jsr afeintrag l106 lda dirtydispf ;Angezeigter Programmname nicht mehr gueltig ora #$04 sta dirtydispf jsr vfausw ;Puffer der Bit's aktualisieren jsr diausw jsr musikausw rts ;rds-puffer auswerten Einsprung bei "RDS-Dirty" rdsausw lda pih ;Hat sich das Programm geaendert? cmp altpi bne l59 lda pil cmp altpi+1 beq l60 ;Nein, weiter l59 jsr neuerpi ;Sonst alles loeschen lda pih sta altpi lda pil ;und neuen PI-Code merken sta altpi+1 jsr piwand ;PI-Code in ASCII wandeln lda datenzeile ;Dirtyflag falls PI gerade dargestellt wird cmp #$02 bne l60 lda dirtydispf ora #$02 sta dirtydispf l60 lda ki ;VF-Programm-bit holen and #$04 lsr lsr sta tp ;und merken lda ki ;PTY-Code rausholen and #$03 asl asl asl sta ptypuf ;speichern lda po ;und weiter den Rest von PTY holen lsr lsr lsr lsr lsr ora ptypuf ;und endgueltigen PTY-Code merken sta ptypuf jsr ptywand ;in ASCII wandeln lda datenzeile ;und evtl. DIRTY-Display setzen cmp #$01 bne l130 lda dirtydispf ora #$02 sta dirtydispf ;nun die ;"spezialauswertung" -> Auswertung des Uebertragenen Dienstes l130 lda ki ;Blockkennung auswerten and #$f0 lsr lsr lsr tay ;Und als Zeiger auf die Sprungtabelle lda sprungtab,y ;benuetzen sta kzp2 lda sprungtab+1,y sta kzp2+1 ;hier sollte mal jsr ($XXXX) simuliert lda #>[ruecksprung-1] nop ;pha ;werden (das war aber dann doch nicht noetig) lda #<[ruecksprung-1] nop ;pha jmp (kzp2) ruecksprung nop rts ;funktion nicht auswerten nofunktion rts ;radiotext rausholen getrt lda po ;Dienst Radiotext (Kennung $20) and #$1f ;Einfach die 4 Bytes in den RT-Puffer asl ;schreiben (an die richtige Stelle!) asl tay lda byte1 sta rtpuf,y lda byte2 sta rtpuf+1,y lda byte3 sta rtpuf+2,y lda byte4 sta rtpuf+3,y rts ;uhr und mjd holen gettime lda po ;vgl. hierzu die Position der einzelnen and #$01 ;Bits in den Bytes nach Elektor 1/94 clc ror ror sta mjdunkorr+1 lda byte1 clc ror ora mjdunkorr+1 sta mjdunkorr+1 lda #$00 ror sta mjdunkorr lda byte2 lsr ora mjdunkorr sta mjdunkorr lda mjdunkorr sec sbc #<$391e;15019 sta mjd lda mjdunkorr+1 sbc #>$391e;$391e=14622 sta mjd+1 lda datumdirty ora #$01 sta datumdirty lda byte2 and #$01 asl asl asl asl sta kzp1 lda byte3 and #$f0 lsr lsr lsr lsr ora kzp1 sta kzp1 lda byte3 and #$0f asl asl sta kzp1+1 lda byte4 and #$c0 clc rol rol rol ora kzp1+1 sta kzp1+1 sed clc ldx #$ff lda #$99 l79 inx adc #$01 cpx kzp1 bne l79 sta kzp2 clc ldx #$ff lda #$99 l80 inx adc #$01 cpx kzp1+1 bne l80 sta kzp2+1 cld lda kzp2 jsr up1 sta uhr lda kzp2 jsr up2 sta uhr+1 lda kzp2+1 jsr up1 sta uhr+3 lda kzp2+1 jsr up2 sta uhr+4 lda #$30 sta uhr+6 ;Nach einem CT-Code ist es immer sta uhr+7 ;"Null-Sekunden"... daher Sekundenzaehler rts ;loeschen ;pi-code in einen asciipuffer! piwand ldx pitextl lda altpi jsr highhexwand sta asciipi,x inx lda altpi jsr lowhexwand sta asciipi,x inx lda altpi+1 jsr highhexwand sta asciipi,x inx lda altpi+1 jsr lowhexwand sta asciipi,x rts ;highnibble in hexziffer (ascii) highhexwand jsr up1 ;UP1 unteres Nibble in Zahl wandeln l74 cmp #$3a bcc l73 clc adc #$07 l73 rts ;lownibble in hexziffer (ascii) lowhexwand jsr up2 ;UP2 oberes Nibble in Zahl wandeln bne l74 ;alternativfrequenz in ascii ;wandeln afwand ldx afvekt ;Zeiger auf aktuelle AF holen lda afpuf,x ;und AF laden tay sty kzp2 ;merken lda #$75 sta kzp3 lda #$08 sta kzp3+1 ;87.5 MHz laden sed ;Dezimalmodus fuer die Folgende Addition clc cpy #$00 ;Frequenz berechnen beq l110 l111 lda kzp3 clc adc #$01 sta kzp3 lda kzp3+1 adc #$00 sta kzp3+1 dey bne l111 l110 cld ;Nun Werte von BCD nach ASCII wandeln lda kzp3+1 jsr up1 sta afascpuf lda kzp3+1 jsr up2 sta afascpuf+1 lda kzp3 jsr up1 sta afascpuf+2 lda kzp3 jsr up2 sta afascpuf+3 sed ;AF Nummer selber wandeln ldx afvekt inx lda #$00 l113 clc adc #$01 cpx #$00 beq l112 dex bne l113 l112 cld pha ;und jetzt BCD -> ASCII jsr up1 sta afnummer pla jsr up2 sta afnummer+1 ldx #$00 l115 lda aftext,x ; Text "AF" in Displaypuffer beq l114 sta asciiaf,x inx bne l115 l114 lda afnummer ;AF-Nummer im ASCII Format sta asciiaf,x inx lda afnummer+1 sta asciiaf,x inx lda #$20 ;Leerstelle sta asciiaf,x inx ldy #$00 lda afascpuf ;Nun ist die AF selber dran cmp #$30 ;fuehrende Null weglassen bne l116 iny l116 lda afascpuf,y ;Frequenz in Mhz in Ausgabepuffer sta asciiaf,x inx iny cpy #$03 bne l116 lda #"." ;"." zwischen Mhz und 100 khz sta asciiaf,x inx lda afascpuf+3 ;100khz in den Ausgabepuffer sta asciiaf,x inx lda #$20 ;und Rest vom Display-Puffer loeschen l131 sta asciiaf,x inx cpx #$10 ;Ende fertig bne l131 rts ; Speicher mit Konstanten vorbelegen (Ist ein Teil von RESET) ; ---------------------------------------------------------- konstsp ldx #$00 lda #$30 l15 sta uhr,x ;Uhr mit 00:00:00 vorbelegen inx cpx #$08 bne l15 lda #":" sta uhr+2 sta uhr+5 jsr datumber ;"Datum" berechnen lda #rtpuf sta zeile2vekt+1 jsr neuerpi ;Speicher mit Leerstellen und so fuellen ldx #$00 l21 lda rttext,x ;Startradiotext in den Puffer beq l20 sta rtpuf,x inx bne l21 l20 ldx #$80 ;Max 128 Zeichen zum Scrollen stx scrollges ldx #$00 ;Text "PI-Code" in den Puffer l70 lda pitext,x beq l71 sta asciipi,x inx bne l70 l71 lda #$20 l125 sta asciipi,x ;Leerzeichen = Rest loeschen inx cpx #$10 bne l125 lda #$01 ;Scrollen ein sta scrollf lda #01 sta datumdirty ;Datum ist dirty ldx #$00 l126 lda #$20 sta asciiaf,x ;Alle moeglichen Puffer mit Leerstellen lda ptytab,x ;loeschen sta asciipty,x lda ditext,x sta asciidi,x inx cpx #$10 bne l126 lda #startwertmjd sta mjd+1 jsr piwand rts ;verkehrsfunkprg darstellen vfausw lda tp ;VF ja/nein laden and #$01 asl asl asl ;*16 als Zeiger auf ASCII-String asl tay ldx #$00 l144 lda vftab,y ;Entsprechenden String laden sta asciivf,x iny inx cpx #$10 bne l144 lda datenzeile ;Wenns dargestellt wird Dirty-Display cmp #$06 bne l148 lda dirtydispf ora #$02 sta dirtydispf l148 rts ;musik/sprache flag in ascii musikausw lda musik ;im Prinzip das gleiche wie bei VF-Flag and #$01 asl asl asl asl tay ldx #$00 l146 lda musiktab,y sta asciimusik,x iny inx cpx #$10 bne l146 lda datenzeile cmp #$05 bne l149 lda dirtydispf ora #$02 sta dirtydispf l149 rts ;di-flag in ascii wandeln diausw lda di jsr lowhexwand ldx ditextl sta asciidi,x lda datenzeile cmp #$07 bne l150 lda datenzeile ora #$02 sta datenzeile l150 rts ; Hauptinterrupt ; --------------------------------------------------------- ; (war: Zeile 40000) irq pha ;Register sichern txa pha tya pha cld ;Dezimalmodus aus lda ifr ;IFR von VIA6522 laden sta irqkzp ;und merken and #$01 ;IRQ durch CA2 (Startsync)? bne ca2irq ;Ja, 3 Bytes lesen ; lda irqkzp ; and #$04 ;Waere mal Schieberegistereingabe gewesen ; bne srirq lda irqkzp and #$40 ;IRQ durch Timer 1? bne timer1irq ;Yepp, Uhr weiterzaehlen beq tastabfr ;sonst nur Tastatur abfragen timer1irq lda timer1l ;Interrupt loeschen inc irqcount2 ;Scrollhilfzaehler erhoehen lda irqcount2 ;Schon 4. Durchgang? and #$03 bne l81 ;Nein, kein Scrolling lda scrollf ;Sonst um eins weiterscrollen beq l81 ;Ueberhaupt im Scrollmode? inc rtvekt lda rtvekt cmp scrollges bne l82 lda #$00 sta rtvekt l82 lda dirtydispf ;Und Display ist dirty ora #$02 sta dirtydispf l81 inc counter ;Zaehler um 1 sec auszuzaehlen lda counter cmp #25 ;1 Sekunde um? bne tastabfr ;nein? -> Tastatur abfragen lda #$00 sta counter jsr uhrkorr ;Uhr neu wandeln tastabfr lda tastpuf ;War im letzten Durchgang schon eine Taste bmi endetast ;gedrueckt? -> ja, dann Ende lda porta and #$78 ;Sonst Port laden und Tasten maskieren beq l41 lsr lsr lsr ora #$80 ;gedrueckte Taste merken sta tastpuf jsr tasteausw ;Auswerten jmp endeirq ;und IRQ-Routine beenden endetast lda porta ;Ist die Taste noch gedrueckt? and #$78 bne l40 ;Ja, nix veraendern lda #$00 ;"Taste gedrueckt" loeschen beq l41 l40 lda tastpuf l41 sta tastpuf endeirq pla ;Register wiederherstellen tay pla tax pla rti ;bitweisen einlesen der ;rds-daten ca2irq ldx #$03 ;3 Bytes einlesen lda #$00 l133 sta dreibytepuf-1,x ;Puffer loeschen dex bne l133 lda #$00 sta timer2l ;Timer 2 setzen lda #$50 ;(ist im Moment nicht genutzt) sta timer2h l137 ldy #$08 ;auf Clock low warten l136 lda #$02 l134 bit porta bne l134 l135 bit porta ;auf Clock high warten beq l135 lda porta ;also quasi mit steigender Flanke DATA lesen and #$04 ;(Bit 2 im Port A = DATA) ror ror ror rol dreibytepuf,x ;In den Puffer schieben dey bne l136 ;schon alle 8 Bits? inx ;schon 3 Bytes? cpx #$03 bne l137 ;nein, weitermachen mit lesen ldx #$00 ;Register als Zeiger nutzen ldy pufvekt ;Teil des Datensatzes gelesen? bne l139 ;sonst auf Null testen l140 lda dreibytepuf,x beq l139 inx cpx #$03 bne l140 jmp endeirq ;Keine Null --> Daten wegwerfen l139 lda dreibytepuf,x ;Puffer in den RDS-Datenpuffer sta rdspufa,y iny inx cpx #$03 bne l139 sty pufvekt cpy #12 ;schon alle 12 Bytes eines RDS Pakets? bcc l141 ;nein, beenden ldy #$00 sty pufvekt ;Sonst auf die 0,1,2,3 Folge testen lda rdspufa+3 cmp #$01 bne l141 lda rdspufa+6 cmp #$02 bne l141 lda rdspufa+9 ;Nicht 0,1,2,3 an der richtigen Stelle cmp #$03 ;Datenblock ungueltig bne l141 lda rdsdirty ;Letzten Datenblock schon verarbeitet? bne l141 ;Nein? Dann diesen Block wegwerfen! ora #$01 sta rdsdirty ;Sonst "neuer Datensatz da" setzen ldx #$00 l142 lda rdspufa,x ;und in den Arbeitspuffer sta rdspuf,x inx cpx #12 bne l142 l141 jmp endeirq ;Ende ;Uhr weiterzaehlen uhrkorr lda dirtydispf ;Uhr um 1 Sekunde weiterzaehlen ora #$01 ;dadurch wird der Decoder autark, also sta dirtydispf ;unabhaengig vom CT Signal was viele ldy #$30 ;kommerzielle Teile nicht gebacken kriegen ;-) inc uhr+7 lda uhr+7 cmp #$3a bne endeuhrkorr sty uhr+7 inc uhr+6 lda uhr+6 cmp #$36 bne endeuhrkorr sty uhr+6 inc uhr+4 lda uhr+4 cmp #$3a bne endeuhrkorr sty uhr+4 inc uhr+3 lda uhr+3 cmp #$36 bne endeuhrkorr sty uhr+3 inc uhr+1 lda uhr+1 cmp #$34 beq nichtnulluhr l19 cmp #$3a bne endeuhrkorr sty uhr+1 inc uhr endeuhrkorr rts nichtnulluhr lda uhr cmp #$32 ;auf 23:59:59 testen, wenn ja, Uhr rueck- bne l19 ;setzen und Datumsumschaltung sty uhr sty uhr+1 inc mjd bne l27 inc mjd+1 l27 lda datumdirty ora #$01 sta datumdirty lda dirtydispf ora #$02 sta dirtydispf rts ;datum im binaerformat ;aus mjd berechnen altjahr equ kzp1 ;Dieses hier ist der groesste Brocken h equ zpadd1 ;und ein Programmteil der ebenso tm equ kzp2 ;in bisher KEINEM kommerziellem Teil datumber lda #$00 ;gesichtet wurde sta jahr ;hierzu empfiehlt sich das Basic-Programm sta altjahr ;und den Elektorartikel 1/94 zu lesen sta mr sta mr+1 ;Erstmal alle Puffer loeschen sta zw sta zw+1 sta monat lda #$01 sta tag sec ;MJD holen (Binaer) in "Tag des lda mjd ;Jahrhunderts" sbc #<0365 lda mjd+1 sbc #>0365 ;Sind mir im Jahr 0? bcc monatsuche ;Ja, gleich den Monat berechnen jahrinc lda zw ;Sonst erstmal das Jahr suchen sta mr lda zw+1 ;MIT Beruecksichtigung von Schaltjahren sta mr+1 lda jahr sta altjahr inc jahr lda zw clc adc #<0365 ;Jahr Null ist schon weg und sta zw ;beruecksichtigt, das KEIN Schaltjahr lda zw+1 adc #>0365 sta zw+1 lda altjahr beq keinschalt and #$03 bne keinschalt clc lda zw adc #$01 ;Hier wird das Schaltjahr beruecksichtigt sta zw lda zw+1 adc #$00 sta zw+1 keinschalt lda zw sec sbc mjd ;Schon MJD "ueberholt"? sta h lda zw+1 sbc mjd+1 sta h+1 bcc jahrinc ;Nein? Dann weiter Jahreszaehler erhoehen monatsuche lda altjahr ;Sonst merken und Monat checken sta jahr beq l28 ;Die Monatsberechnung ist im Prinzip and #$03 ;wie die Jahresberechnung, nur beq l24 l28 ldx #$00 ;das hier eine Tabelle im ROM genutzt beq l25 ;wird wo die Monatslaengen gespeichert l24 ldx #12 ;sind... l25 lda mjd ;Auch hier werden Schaltjahre sec ;beruecksichtigt! sbc mr sta tm lda mjd+1 sbc mr+1 sta tm+1 txa asl tax ldy #$00 ; neue Variablen....jaja ich gebs zu ich war zu faul das Basicprogramm ; nochmal neu zu uebersetzen x equ kzp1 z equ kzp3 sty x sty z monatinc lda z sta x lda z+1 sta x+1 iny lda monatstab,x sta z sec sbc tm lda monatstab+1,x sta z+1 sbc tm+1 bcs monatfound inx inx bne monatinc monatfound sty monat ;Monat gefunden... Dann nur noch den lda tm ;Tag rausfinden (uff) sec sbc x sta tag ;FERTIG mit der Rechnerei bne datumda inc tag datumda sed ;Jetzt nur noch in ASCII wandeln clc ;passiert wie ldx #$00 ;schon weiter oben beschrieben lda #$99 l29 adc #$01 ;Vorbereitung Binaer -> BCD wandeln inx cpx tag bne l29 sta tag clc ldx #$00 lda #$99 l30 adc #$01 inx cpx monat bne l30 sta monat ldx jahr txa beq l33 clc ldx #$00 lda #$99 l32 adc #$01 inx cpx jahr bne l32 l33 cld ;Nun von BCD -> ASCII (einfach) sta jahr lda tag jsr up1 sta datum lda tag jsr up2 sta datum+1 lda monat jsr up1 sta datum+2 lda monat jsr up2 sta datum+3 lda jahr jsr up1 sta datum+4 lda jahr jsr up2 sta datum+5 rts ;unterprogramm zu datumber up1 lsr ;HIGH-Nibble BCD wandeln nach ASCII Zahl lsr lsr lsr ora #$30 rts up2 and #$0f ;dito mit dem low-Nibble ora #$30 rts ;keine nmi routine, da nicht ;beschaltet! nmi rti ;falls es mal nen' NMI gibt stuerzt der ;Rechner nicht ab ;tastatur auswerten tasteausw lda #$01 bit tastpuf bne taste1ged asl bit tastpuf bne taste2ged asl bit tastpuf bne taste3 asl bit tastpuf bne taste4 tastabsch lda tastpuf and #$0f cmp #$0f beq gig rts taste3 jmp taste3ged taste4 jmp taste4ged gig jmp gag ;rds-dienst-taste=taste1 taste1ged lda sendtabf bne tastabsch inc datenzeile lda datenzeile cmp maxdatenz bne l86 lda #$00 sta datenzeile l86 asl tay ldx #$00 l87 lda zeile2vekttab,y sta zeile2vekt,x iny inx cpx #$02 bne l87 lda #$00 sta scrollf sta rtvekt lda datenzeile bne l88 inc scrollf l88 lda dirtydispf ora #$02 sta dirtydispf lda afdirty ora #$80 sta afdirty jmp tastabsch ;+ taste gedrueckt taste2ged lda afvekt cmp afplatz beq l90 clc adc #$01 cmp afplatz bne l89 l90 lda #$00 l89 sta afvekt lda sendtabf beq taste2ende lda zeile2vekt clc adc #$18 sta zeile2vekt lda zeile2vekt+1 adc #$00 sta zeile2vekt+1 lda zeile2vekt cmp sendtabende bne l91 lda zeile2vekt+1 cmp sendtabende+1 bne l91 lda sendtabanf sta zeile2vekt lda sendtabanf+1 sta zeile2vekt+1 l91 ldy #$10 ldx #$00 l92 lda (zeile2vekt),y sta pspuf,x iny inx cpx #$08 bne l92 lda dirtydispf ora #$06 sta dirtydispf taste2ende lda dirtydispf ora #$02 sta dirtydispf lda afdirty ora #$80 sta afdirty jmp tastabsch ;- taste gedrueckt taste3ged lda afvekt beq l96 sec sbc #$01 bpl l97 l96 lda afplatz beq l97 sec sbc #$01 l97 sta afvekt lda sendtabf beq taste3ende lda zeile2vekt cmp sendtabanf bne l98 lda zeile2vekt+1 cmp sendtabanf+1 bne l98 lda sendtabende sta zeile2vekt lda sendtabende+1 sta zeile2vekt+1 bne l100;unbed sprg l98 lda zeile2vekt sec sbc #$18 sta zeile2vekt lda zeile2vekt+1 sbc #$00 sta zeile2vekt+1 l100 ldy #$10 ldx #$00 l101 lda (zeile2vekt),y sta pspuf,x iny inx cpx #$08 bne l101 lda dirtydispf ora #$04 sta dirtydispf taste3ende lda dirtydispf ora #$02 sta dirtydispf lda afdirty ora #$80 sta afdirty jmp tastabsch ;sendertabelle aktivieren ;bzw. desaktivieren taste4ged lda sendtabf eor #$01 sta sendtabf beq l102 lda sendtabanf sta zeile2vekt lda sendtabanf+1 sta zeile2vekt+1 lda portb ora #$02 sta portb lda dirtydispf ora #$03 sta dirtydispf lda #$00 sta rtvekt sta scrollf ldx #$00 l127 lda sendtab1+$10,x sta pspuf,x inx cpx #$08 bne l127 lda dirtydispf ora #$04 sta dirtydispf jmp tastabsch l102 lda portb and #$fd sta portb lda datenzeile jmp l86 ;wenn alle tasten gedrueckt ;werden: uhr auf 23.59 uhr gag lda #$32 sta uhr lda #$33 sta uhr+1 lda #$35 sta uhr+3 lda #$39 sta uhr+4 rts ;allerlei tabellen und text lcdinittab dc.b $38,$01 dc.b $02,$06,$0c,$18 ;einschaltmeldung promptz1 dc.b " 6502 RDS-Dekoder" dc.b $00 promptz2 dc.b " (c)Sep 94 by CG " dc.b $00 ;startradiotext nach dem ein- ;schalten rttext dc.b "Soft und Hardware im Herbst 1994 von Carsten" dc.b " Gross entwickelt! " dc.b "2K RAM, 8K ROM, 6502 Mikroprozessor-Syst" dc.b "em! Port: 6522 ##" dc.b $00 monatstab dc.w 31,59,90,120,151 dc.w 181,212,243,273,304,334,365 dc.w 31,60,91,121,152,182,213,244 dc.w 274,305,335,366 ;tabelle der wochentage wochttab dc.b "--------" dc.b "Mittwoch" dc.b "Donn.tag" dc.b "Freitag " dc.b "Samstag " dc.b "Sonntag " dc.b "Montag " dc.b $00 dc.b "Dienstag" ;tabelle der ptykennungen ptytab dc.b " Keine Kennung " dc.b " Nachrichten " dc.b " Zeitgeschehen " dc.b " Information " dc.b " Sport " dc.b " Weiterbildung " dc.b " Hrspiel " dc.b " Kultur " dc.b " Wissenschaft " dc.b " Unterhaltung " dc.b " Popmusik " dc.b " Rockmusik " dc.b "Unterhaltungsmu." dc.b " L-Klassik " dc.b " E-Klassik " dc.b " ALARM " ;neuer zeichensatz ab $00-$07 ;reihenfolge ;klein g,gross ae,gross oe, gross ue, gradzeichen anzahlz dc.b $28 zeichens dc.b $00,$00,$0d,$12,$12,$0e,$02,$0c dc.b $0a,$04,$0a,$11,$1f,$11,$11,$00 dc.b $0a,$0e,$11,$11,$11,$11,$0e,$00 dc.b $0a,$11,$11,$11,$11,$11,$0e,$00 dc.b $1c,$14,$1c,$00,$00,$00,$00,$00 ;text zur initalisierung pitext dc.b "PI-Code: $" dc.b $00 pitextl dc.b $0a ;sprungtabelle zur auswertung ;des rds-ki bytes sprungtab dc.w getps dc.w nofunktion,getrt ;$10,$20 dc.w nofunktion,gettime ;$30,$40 dc.w nofunktion,nofunktion ;$50,$60 dc.w nofunktion,nofunktion ;$70,$80 dc.w nofunktion,nofunktion ;$90,$a0 dc.w nofunktion,nofunktion ;$b0,$c0 dc.w nofunktion,nofunktion ;$d0,$e0 dc.w getps ;$f0 ;psget tabelle hilfstab dc.b $fe,$fd,$fb,$f7,$ef zeile2vekttab dc.w rtpuf,asciipty,asciipi,asciidatum,asciiaf,asciimusik dc.w asciivf,asciidi maxdatenz dc.b $08 aftext dc.b "af" dc.b $00 vftab dc.b "Kein Verkehrsf. " dc.b "Verkehrsfunk " musiktab dc.b " Sprache " dc.b " Musik " ditext dc.b "DI-Nibble: $X " ditextl dc.b $0d ;sendertabelle fuer bolheim sendtabanf dc.w sendtab1 sendtabende dc.w sendtab2 sendtab1 dc.b "92,6 mhz 208 sdr1 " dc.b "89,2 mhz 208 s2kultur" dc.b "97,4 mhz 208 sdr3 " dc.b "99,9 mhz 201 drs1 " dc.b "95,4 mhz 201 drs2 " dc.b "105,6 mhz 201 drs3 " dc.b "90,7 mhz 174 bayern1 " dc.b "88,7 mhz 174 bayern2 " dc.b "95,8 mhz 174 bayern3 " dc.b "101,0 mhz 174 bayern4 " dc.b "93,3 mhz 192 oe 1 " dc.b "98,2 mhz 192 oe 2-v " dc.b "89,6 mhz 192 oe 3 " dc.b "102,1 mhz 192 blue dan" dc.b "98,7 mhz 174 swf1 bw " dc.b "103,0 mhz 174 swf3 " dc.b "104,4 mhz 174 antenne " dc.b "94,0 mhz 208 donau 1 " dc.b "100,1 mhz 343 regional" dc.b "100,0 mhz 116 afn " dc.b "94,5 mhz 208 s4 bw ul" dc.b "91,2 mhz 211 s4 bw rv" dc.b "106,9 mhz 174 bayern5 " dc.b "101,8 mhz 208 radio7ul" sendtab2 dc.b "105,0 mhz 211 radio7rv" dc.b $ff,$ff,$ff dc.w nmi dc.w reset dc.w irq end