; Programm: PRG6.ASM
LIST P=16C84

; * Symbolzuweisungen *
        W        EQU 0
        f        EQU 1
        STATUS_R EQU 03h
        PORT_A   EQU 05h
        PORT_B   EQU 06h
        EEDATA_R EQU 08h
        EEADR_R  EQU 09h
        INTCON_R EQU 0Bh
        OPTION_R EQU 81h
        TRIS_A   EQU 85h
        TRIS_B   EQU 86h
        EECON1_R EQU 88h
        EECON2_R EQU 89h

        #DEFINE Zero     STATUS_R,2
        #DEFINE Page_1   STATUS_R,5
        #DEFINE RD       EECON1_R,0
        #DEFINE WR       EECON1_R,1
        #DEFINE WREN     EECON1_R,2
        #DEFINE EEIF     EECON1_R,4
        #DEFINE RD_Con   PORT_A,0
        ; Controllbit fuer das Lesen
        #DEFINE WR_Con   PORT_A,1
        ; Controllbit fuer das Schreiben
        #DEFINE Wait_Con PORT_A,2
        ; Controllbit fuer den Schreibenzyklus
        ; im EEPROM des Datums

; * Definieren des Resetvektors *
ORG 0000h
        GOTO Start

; * Definieren des Startvektors *
ORG 01FFh
        GOTO Start

; * Definieren des Hauptprogrammadresse *
ORG 0010h

; * Hauptprogramm *
Start:  
; * Initialiesiern der Register *
        CLRF    INTCON_R
                ; Alle Interrupts aus.
        BSF     Page_1   
        ; Umschalten auf Seite 1 der Registerseite
        CLRF    TRIS_A
                ; PortA alle auf AUSgabe
        CLRF    TRIS_B
                ; PortB alle auf AUSgabe
        CLRF    OPTION_R
                ; OPTION-Register
                ;  Pull-Up ein (wirkungslos, 
                ;       da Port auf Ausgabe)
                ;  Timereinagng: CLKOUT (fosc/4)
                ;  Vorteiler: aus
        CLRF    EECON1_R
                ; Loeschen des Inhaltes in EECON1
        CLRF    EECON2_R
                ; Loeschen des Inhaltes in EECON2
        BCF     Page_1
                ; Zurueckschalten von Seite 1 auf 
                ;     Seite 0 der Registerseiten
        CLRF    EEDATA_R
                ; Loeschen des Inhaltes in EEDATA
        CLRF    EEADR_R
                ; Loeschen des Inhaltes in EEADR

        
; * SCHREIBEN der EEPROM mit Daten *
; Kurzbeschreibung:
;   Das Programm soll den ganzen EEPROM-
;   Speicher (00h-3Fh, 64 Bytes) mit dem
;   Wert der Summe aus dem Wert der Adresse mit
;   der Konstante 64d bzw. 40h beschreiben.
;       [EEDATA]=[EEADR]+40h
;   PortB dient als Zaehlermonitor der EEPROM-
;   Adressierung. Waehrend dem ganzen Beschreiben 
;   wird an PortA Bit 1 ein Write-Controllbit
;   - WR_Con - ausgegeben. Und bei dem 
;   Beschreiben und Abwarten der Beendigung des 
;   EEPROM-Schreibezyklus wird ein weiteres 
;   Meldebit Wait_Controllbit - Wait_Con - an
;   PortA Bit 2 ausgegeben.

; - Initalisieren der Ports
        CLRF    PORT_B
        CLRF    PORT_A
        BSF     WR_Con

; - Schreiberoutinen
Write:  
        ; # Setzen des WREN-Bit im EECON1 (Seite 1)
        BSF     Page_1
        BSF     WREN
        BCF     Page_1

        ; # Inhalt von PortB in W und in EEADR
        MOVF    PORT_B,W
        MOVWF   EEADR_R
               
        ; # Inhalt von PortB in W und Addition
        ;   des Wertes 64d, speichern in EEDATA
        MOVF    PORT_B,W
        ADDLW   d'64'
        MOVWF   EEDATA_R

        ; # EEPROM-Schreibsequenz !!!
        BSF     Page_1   
                ; Umschalten auf Seite 1 (Reg.)
        MOVLW   55h
        MOVWF   EECON2_R 
                ; EECON2=55h setzen
        MOVLW   0AAh
        MOVWF   EECON2_R 
                ; EECON2=0AAh setzen
        BSF     WR
                ; Setzen des WR-Bit im EECON1
        BCF     Page_1
                ; Zurueckschalten.

        ; # Kennzeichnung, dass EEPROM-Schreib-
        ;   Warte-Sequenz abgeschlossen ist,
        ;   mit setzen des Wait_Con.
        BSF     Wait_Con

        ; # Warteschelife bis EEPROM-Zeile
        ;   geschrieben worden ist mit der
        ;   Ueberpruefung des EEprom-Interrupt-Flags
        ;   ! Umschalten auf Seite 1 d. Reg.-S. !
        BSF     Page_1
Warten: BTFSS   EEIF
          GOTO  Warten

        ; # Loeschen des Wait_Con
        BCF     Wait_Con

        ; # Loeschen des EEprom-Interrupt-Flags
        BCF     EEIF

        ; # Zurueckschalten auf Seite 0
        BCF     Page_1

        ; # Zaehlsequenz von 00h bis 3Fh und 
        ;   Rueckkehr zu Schreibroutine
        ;   bei 40h austeigen.
        INCF    PORT_B,f
        MOVF    PORT_B,W
        SUBLW   d'64'
        BTFSS   Zero
          GOTO  Write

        ; # Umschalten des PortB auf Eingang.
        BSF     Page_1
        MOVLW   0FFh
        MOVWF   TRIS_A
        BCF     Page_1

; * LESEN der EEPROM mit Daten *
; Kurzbeschreibung:
;   In dieser Teilprogramm wird das Register fuer
;   die EEPROM-Adressierung (EEADR) von 00h bis
;   3Fh inkrementiert. Vor jeder Inkrementation 
;   wird der Inhalt dieser Adresse ausgelesen und
;   auf dem PortB ausgegeben. Bei dieser ganzen 
;   Aktion ist das RD-Controllbit (RD_Con) am 
;   PortA-Bit 0 (PA0) gleich 1. Nach Beendigung
;   der 64 Auslesezyklen des EEPROM verhart das 
;   System in eine Endlosschleife.

        ; # Loeschen des EEADR-Register, wegen
        ;   Zaehlerstandes!
        CLRF    EEADR_R

        ; # Setzen des RD_Controllbits an PA0
        BSF     RD_Con

; - Leseroutinen        
Read:   
        ; # Setzen des RD im EECON1
        ;   (Um & Zurueckschalten auf Seite 1)
        BSF     Page_1
        BSF     RD
        BCF     Page_1

        ; # Auslesen der Daten aus dem EEDATA-Reg.
        MOVF    EEDATA_R,W
        
        ; # Datzen auf PortB schreiben
        MOVWF   PORT_B     
        
; Bemerkung: Nach der Exekution des MOVWF PORT_B
;            Zeile ist der Inhalt des EEPROMs
;            am PortB (-> Simulator)

        ; # Zaehlsequenz von 00h bis 3Fh und 
        ;   Rueckkehr zu Leseroutine
        ;   bei 40h austeigen.
        INCF    EEADR_R,f
        MOVF    EEADR_R,W
        SUBLW   d'64'
        BTFSS   Zero
          GOTO  Read

        ; # Loeschen des PortA
        CLRF    PORT_A

; * Endlosschleife
Marke   NOP
        GOTO    Marke

; Bemerkung: Wenn man dieses Programm mittels
;   dem Simulator analysiert, sieht man genau
;   die Verarbeitung der Signale.
;            Es treten 13 Meldungen auf, dass
;   das hoechstwertige Bit ignoriert wird,
;   dieses hat zur Folge das eine Register-
;   adressierung ueber den Wert 80h nicht 
;   adressiert werden kann, da bei einer
;   Registeradressierung nur 7 Bit (statt 8)
;   zur Verfuegung stehen und daher auf die
;   erste Seite der Registerseitenadressierung
;   umgeschaltet werden muss.
END

