;Programm fr einen Universalempf„nger basierend auf dem Lauflichtkonzept


.incld cop880.inc
.sect main,rom,abs=0

ASICHER		= 00H
BSICHER 	= 01H
XSICHER 	= 02H
BACKUP		= 03H
BYTE2		= 04H
SNDBUF          = 05H
RDATL           = 06H
RDATH           = 07H
WDATL           = 08H
WDATH           = 09H
ADRESS          = 0AH
FLAGS           = 0BH
PSWSICHER	= 0CH
TASTE		= 0DH
RECEIVEMODE	= 0EH
TIMERDATA	= 0FH
REGISTER	= 010H
DATACODE	= 011H
PARYREGISTER	= 012H

PARYZAEHLER	= 0F6H
OUTZAEHLER	= 0F9H
DLYH            = 0FAH  ;-
DLYL            = 0FBH  ;-
;Bei FB ist Schluá!

;Pinbelegung:	G0		Infrarotempf„nger
;		G1		Codierung
;		G2		Eeprom CS
;		G3		Trigger bei Tastendruck
;		G4		Eeprom output (DO)
;		G5		Eeprom Microwire clock
;		G6		Eeprom input (DI)

;		L0		Treibersteuerung
;		L1			#
;		L2			#
;		L3			#
;		L4			#
;		L5			#
;		L6			#
;		L7			#

;Taktfrequenz = 10MHz

;************************************************
;*              Initialisierung                 *
;************************************************

UNI:
	LD      B,#0FDH         ;Clear Ram
RAM:    LD      [B],#0          ;
	DRSZ    B               ;
	JP      RAM             ;
	LD      0,#0            ;
	LD      PORTLC,#0FFH    ;Alle L-Pins als Ausgang Low
	LD      PORTLD,#0	;
	LD      PORTCC,#0FFH    ;Alle C-Pins als Ausgang Low
	LD      PORTCD,#0       ;
	LD      PORTDD,#0       ;Alle D-Pins als Ausgang Low
	LD      PORTGC,#B'00111100;G0,G1 Pull up
	LD	PORTGD,#B'00000011;
	LD      SP,#06FH        ;Stackpointer auf oberste Ramadresse
	LD      B,#TMRLO        ;
	LD      [B+],#08FH      ;0.4ms Interrupt
	LD      [B+],#01H       ;
	LD      [B+],#08FH      ;
	LD      [B],#01H        ;
	LD      CNTRL,#0AH      ;Enable Microwire
	JSR	EEREAD		;Adresse 0 und 1 im Eeprom auslesen
	SBIT    7,CNTRL         ;Timer Mode
	LD      PSW,#011H       ;Enable Timer-Interrupt
				;Enable General-Interrupt
	SBIT	GIE,PSW		;Alle Interrupts zulassen
	SBIT    4,CNTRL         ;Timer anschalten


;************************************************
;*		Hauptprogramm			*
;************************************************

				;DO FOREVER
LOOP:	LD      A,RECEIVEMODE   ;       IF Receivemode = 20
	IFEQ    A,#020H         ;
	JP      LOOP2           ;
	JP      LOOP3           ;
LOOP2:  JSR     AUSWERTUNG      ;       THEN CALL 'Auswertung'
LOOP6:	LD      RECEIVEMODE,#0  ;            Receivemode = 0
	LD      OUTZAEHLER,#8   ;            Outzaehler = 8      
	LD      TIMERDATA,#0    ;            Timerdata = 0
	JP      LOOP            ;
LOOP3:  IFEQ    A,#0FFH         ;       ELSE IF ERROR
	JP      LOOP6           ;            THEN Alle Register l”schen
				;            ENDIF
				;       ENDIF
	JP	LOOP		;
				;END DO FOREVER

.=0FFH

;************************************************
;*              Interrupt                       *
;************************************************

	X       A,ASICHER       ;
	LD      A,B             ;
	X       A,BSICHER       ;
	LD	A,PSW		;
	X	A,PSWSICHER	;
TIMEINT:RBIT    TPND,PSW        ;Pending Flag l”schen
	LD      A,RECEIVEMODE   ;IF Receivemode = 0
	IFEQ    A,#0            ;
	JP      P10             ;THEN GOTO 'P10'
	IFEQ    A,#1            ;ELSE IF Receivemode = 1
	JP      P20             ;     THEN GOTO 'P20'
	IFEQ    A,#2            ;     ELSE IF Receivemode = 2
	JP      P30             ;          THEN GOTO 'P30'
	IFEQ    A,#010H         ;               ELSE IF Receivemode = 10
	JP      P50             ;                    THEN GOTO 'P50'
	IFEQ    A,#011H         ;                    ELSE IF Receivemode = 11
	JP      P60             ;                         THEN GOTO 'P60'
				;                         ENDIF
				;                    ENDIF
				;               ENDIF
				;          ENDIF
				;     ENDIF
				;ENDIF
P80:    LD      A,RECEIVEMODE   ;IF Receivemode = 20
	IFEQ    A,#020H         ;
	JP      P81             ;THEN GOTO 'P81'
	IFEQ    A,#0FFH         ;     ELSE IF Receivemode = FF
	JP      P81             ;          THEN GOTO 'P81'
	LD      A,TIMERDATA     ;          ELSE Timerdata = Timerdata + 1
	RC                      ;
	ADC     A,#1            ;
	X       A,TIMERDATA     ;
	IFC                     ;               IF šberlauf
	LD      RECEIVEMODE,#0FFH;              THEN Receivemode = FF
				;               ENDIF
				;          ENDIF        
				;     ENDIF
				;ENDIF
P81:
INT1:	LD	A,PSWSICHER	;
	AND	A,#B'11000000	;
	RBIT	7,PSW		;
	RBIT	6,PSW		;
	XOR	A,PSW		;
	X	A,PSW		;
	LD      A,BSICHER       ;
	X       A,B             ;
	LD      A,ASICHER       ;
	RETI

;************************************************
;*		Infrarotsignal auswerten	*
;************************************************

AUSWERTUNG:
	LD      PARYZAEHLER,#0  ;Parityberprfung:
	LD      OUTZAEHLER,#9   ;
	LD      B,#BACKUP       ;
	LD      A,DATACODE      ;
	X       A,[B]           ;
PA2:    DRSZ    OUTZAEHLER      ;
	JP      PA3             ;
	JP      PA4             ;
PA3:    LD      A,BACKUP        ;
	RC                      ;
	RRC     A               ;
	X       A,BACKUP        ;
	IFNC                    ;
	JP      PA2             ;       
	LD      A,PARYZAEHLER   ;
	ADD     A,#1            ;
	LD      B,#PARYZAEHLER  ;
	X       A,[B]           ;
	JP      PA2             ;
PA4:    IFBIT   0,PARYZAEHLER   ;IF Paryzaehler = ungerade
	JP      PA5             ;
	JP      PA6             ;
PA5:    IFBIT   0,PARYREGISTER  ;THEN IF NOT Bit 0,Paryregister
	JP      OK              ;     THEN RET
	RET                     ;     ENDIF
PA6:    IFBIT   0,PARYREGISTER  ;ELSE IF Bit 0,Paryregister
	RET                     ;     THEN RET
				;     ENDIF
				;ENDIF
OK:	LD	A,DATACODE	;'Taste' = 'Datacode'
	X	A,TASTE		;
	IFBIT	1,PORTGP	;IF Pin G1 = Low (Variante 2)
	JP	PINHIGH		;
	LD	A,TASTE		;THEN Gebe Scan-Code an Pins L0-L7 aus
	X	A,PORTLD	;
SPEICHERN:			;
	SBIT	3,PORTGD	;     Triggersignal an G3 ausgeben
	LD	A,PORTLD	;
	X	A,TASTE		;
	JSR	EEWRITE		;     Zustand abspeichern
	RBIT	3,PORTGD	;
	RET			;
PINHIGH:LD	A,TASTE		;ELSE IF Taste 'Return'
	IFEQ	A,#05AH		;                    
	JP	RETU		;
	JP	TAS1		;
RETU:	LD	PORTLD,#0	;     THEN Alle Pins L0-L7 low
	JP	SPEICHERN	;          Zustand abspeichern
TAS1:	IFEQ	A,#016H		;     ELSE IF Taste '1'
	JP	TASTE1		;
	JP	TAS2		;
TASTE1:	IFBIT	0,PORTLD	;          THEN Zustand von L0 toggeln
	JP	L0AUS		;
	SBIT	0,PORTLD	;
	JP	SPEICHERN	;
L0AUS:	RBIT	0,PORTLD	;
	JP	SPEICHERN	;              und speichern
				;          ENDIF

TAS2:	IFEQ	A,#01EH		;          IF Taste '2'
	JP	TASTE2		;
	JP	TAS3		;
TASTE2:	IFBIT	1,PORTLD	;          THEN Zustand von L1 toggeln
	JP	L1AUS		;
	SBIT	1,PORTLD	;
	JP	SPEICHERN	;
L1AUS:	RBIT	1,PORTLD	;
	JP	SPEICHERN	;              und speichern
				;          ENDIF

TAS3:	IFEQ	A,#026H		;          IF Taste '3'
	JP	TASTE3		;
	JP	TAS4		;
TASTE3:	IFBIT	2,PORTLD	;          THEN Zustand von L2 toggeln
	JP	L2AUS		;
	SBIT	2,PORTLD	;
	JP	SPEICHERN	;
L2AUS:	RBIT	2,PORTLD	;
	JP	SPEICHERN	;              und speichern
				;          ENDIF

TAS4:	IFEQ	A,#025H		;          IF Taste '4'
	JP	TASTE4		;
	JP	TAS5		;
TASTE4:	IFBIT	3,PORTLD	;          THEN Zustand von L3 toggeln
	JP	L3AUS		;
	SBIT	3,PORTLD	;
	JP	SPEICHERN	;
L3AUS:	RBIT	3,PORTLD	;
	JP	SPEICHERN	;              und speichern
				;          ENDIF

TAS5:	IFEQ	A,#02EH		;          IF Taste '5'
	JP	TASTE5		;
	JP	TAS6		;
TASTE5:	IFBIT	4,PORTLD	;          THEN Zustand von L4 toggeln
	JP	L4AUS		;
	SBIT	4,PORTLD	;
	JP	SPEICHERN	;
L4AUS:	RBIT	4,PORTLD	;
	JP	SPEICHERN	;              und speichern
				;          ENDIF

TAS6:	IFEQ	A,#036H		;          IF Taste '6'
	JP	TASTE6		;
	JP	TAS7		;
TASTE6:	IFBIT	5,PORTLD	;          THEN Zustand von L5 toggeln
	JP	L5AUS		;
	SBIT	5,PORTLD	;
	JP	SPEICHERN	;
L5AUS:	RBIT	5,PORTLD	;
	JP	SPEICHERN	;              und speichern
				;          ENDIF

TAS7:	IFEQ	A,#03DH		;          IF Taste '7'
	JP	TASTE7		;
	JP	TAS8		;
TASTE7:	IFBIT	6,PORTLD	;          THEN Zustand von L6 toggeln
	JP	L6AUS		;
	SBIT	6,PORTLD	;
	JP	SPEICHERN	;
L6AUS:	RBIT	6,PORTLD	;
	JP	SPEICHERN	;              und speichern
				;          ENDIF

TAS8:	IFEQ	A,#03EH		;          IF Taste '8'
	JP	TASTE8		;
	JP	TASE		;
TASTE8:	IFBIT	7,PORTLD	;          THEN Zustand von L7 toggeln
	JP	L7AUS		;
	SBIT	7,PORTLD	;
	JP	SPEICHERN	;
L7AUS:	RBIT	7,PORTLD	;
	JP	SPEICHERN	;              und speichern
				;          ENDIF

TASE:	RET


;******************************************************************************
;*      Hier wird der Beginn einer Datenbertragung detektiert
;******************************************************************************
P10:    IFBIT   0,PORTGP        ;IF Pin G0 = 0
	JP      P80             ;
	LD      RECEIVEMODE,#1  ;THEN Receivemode = 1
	LD      TIMERDATA,#0    ;     Timerdata = 0
	JP      P80             ;ENDIF
;******************************************************************************
;Prfen der 6ms Lowphase im Startbit
;******************************************************************************
P20:    IFBIT   0,PORTGP        ;IF Pin G0 = 1
	JP      P201            ;
	JP      P80             ;
P201:	IFBIT	6,REGISTER	;THEN IF NOT Bit Filterbit(6),Register
	JP	P2A		;
	SBIT	6,REGISTER	;     THEN SBIT Filterbit(6),Register
	JP	P80		;
P2A:	RBIT	6,REGISTER	;     ELSE RBIT Filterbit(6),Register
	LD      A,TIMERDATA     ;          IF Timerdata < 4ms
	SC                      ;
	SUBC    A,#10           ;
	IFNC                    ;     
	JP      P70             ;
	SUBC    A,#10           ;          OR Timerdata > 8ms
	IFC                     ;
	JP      P70             ;          THEN ERROR
	LD      RECEIVEMODE,#2  ;          ELSE Receivemode = 2
	LD      TIMERDATA,#1    ;               Timerdata = 1 (wegen Filterbit)
	JP      P80             ;          ENDIF
				;     ENDIF
				;ENDIF
;******************************************************************************
;Prfen der 6ms Highphase im Startbit
;******************************************************************************
P30:    IFBIT   0,PORTGP        ;IF Pin G0 = 0
	JP      P80             ;
	LD      A,TIMERDATA     ;THEN 
	SC                      ;
	SUBC    A,#12           ;
	IFNC                    ;     
	JP      P70             ;     Timerdata < 4,4ms --> ERROR
	SUBC    A,#7            ;vorher 5!!!!
	IFNC                    ;
	JP      P33             ;     Timerdata < 7.6ms --> Prfen 1.Bit
	JP      P70             ;
P33:    LD      RECEIVEMODE,#010H;
P34:    LD      TIMERDATA,#0    ;
	JP      P80             ;

;******************************************************************************
;*      Receive-Mode = 10     Prfen der 1.Lowphase des Codes
;******************************************************************************
P50:    IFBIT   0,PORTGP        ;IF Pin G0 = 1
	JP      P51             ;
	JP      P80             ;
P51:    LD      A,TIMERDATA     ;THEN IF Puls > 0.4ms
	SC                      ;
	SUBC    A,#1            ;
	IFNC                    ;
	JP      P70             ;
	SUBC    A,#6            ;     AND Puls < 2.4ms
	IFC                     ;
	JP      P70             ;
	LD      RECEIVEMODE,#011H;    THEN Receivemode = 011H
	LD      TIMERDATA,#0    ;          Timerdata = 0
	JP      P80             ;     ENDIF
				;ENDIF

;******************************************************************************
;*      Receive-Mode = 11       Prfen der 1.Highphase des Codes
;******************************************************************************
P60:    IFBIT   0,PORTGP        ;IF Pin G0 = 0
	JP      P80             ;
	LD      A,TIMERDATA     ;THEN IF Puls > 0.4ms
	SC                      ;
	SUBC    A,#1            ;
	IFNC                    ;
	JP      P70             ;
	SUBC    A,#4            ;     THEN IF Puls < 1.6ms  vorher 3!!!!!!
	IFNC                    ;
	JP      P61             ;          THEN Carry = 0
	SUBC    A,#2            ;          ELSE IF Puls > 2.8ms
	IFNC                    ;
	JP      P70             ;
	JP      P62             ;               THEN Carry = 1
				;               ENDIF
				;          ENDIF
				;     ENDIF
				;ENDIF
P61:    RC                      ;
	JP      P63             ;
P62:    SC                      ;

;******************************************************************************
;*      Einschreiben der Datenbits
;******************************************************************************
P63:	LD	A,OUTZAEHLER	;IF Outzaehler = 0
	IFEQ	A,#0		;
	JP	PARYSCHREIB	;
	JP	DATASCHREIB	;
PARYSCHREIB:
	IFC			;THEN IF Einsbit empfangen
	JP	EINSPARY	;
	JP	NULLPARY	;
EINSPARY:
	LD	PARYREGISTER,#1	;     THEN Paryregister = 1
	JP	P65		;
NULLPARY:			;
	LD	PARYREGISTER,#0	;     ELSE Paryregister = 0
	JP	P65		;
DATASCHREIB:			;
	LD      A,DATACODE      ;ELSE Rotate Datacode right through Carry
	RRCA                    ;
	X       A,DATACODE      ;
	LD      TIMERDATA,#0    ;     Timerdata = 0
	DRSZ    OUTZAEHLER      ;     Outzaehler = Outzaehler - 1
	NOP			;     IF Outzaehler = 0
	JP      P64             ;
P65:	LD      RECEIVEMODE,#020H;    THEN Receivemode = 020H
	JP      P80             ;
P64:    LD      RECEIVEMODE,#010H;    ELSE Receivemode = 010H
	JP      P80             ;     ENDIF
				;ENDIF

;******************************************************************************
;*      Fehler ist aufgetreten
;******************************************************************************
P70:    LD      RECEIVEMODE,#0FFH;Receivemode = 0FFH
	JP      P80             ;

;************************************************
;*      Lesen eines Registers aus dem EEPROM    *
;************************************************

EEREAD:	JSR     INITEEPROM
	JSR     EWEN
	LD      ADRESS,#0
	JSR     READ
	LD      A,RDATL
	X       A,PORTLD
	RET

;************************************************
;*      Schreiben aller Register ins EEPROM     *
;************************************************

EEWRITE:
	JSR     INITEEPROM
	JSR     EWEN
	LD      A,TASTE
	X       A,WDATL
	LD      A,TASTE
	X       A,WDATH
	LD      ADRESS,#0
	JSR     WRITE
	RET

;********************************************************
;                                                       *
;               EEPROM - ROUTINEN                       *
;                                                       *
;********************************************************

;  SNDBUF          ;CONTAINES THE COMMAND BYTE TO BE WRITTEN TO NMC9306
;  RDATL           ;LOWER BYTE OF THE NMC9306 REGISTER DATA READ
;  RDATH           ;UPPER BYTE OF //   //     //       //  //
;  WDATL           ;LOWER BYTE OF THE DATA TO BE WRITTEN TO NMC9306 REG.
;  WDATH           ;UPPER BYTE OF  //  //  //  //  //    //  //    //

; FLAGS            ;USED FOR SETTING UP FLAGS
		     ;
		     ;FLAG VALUE          ACTION
		     ; 00                 ERASE,ENABLE,DISABLE,ERASE ALL
		     ; 01                 READ CONTENTS OF NMC9306 REGISTER
		     ; 03                 WRITE TO NMC9306 REGISTER
		     ; OTHERS             ILLEGAL COMBINATION

;INITIALIZATION

INITEEPROM:
	LD      B,#PSW
	LD      X,#SIOR
	RET
;
;THIS RUOTINE ERASES THE MEMORY LOCATION POINTED TO BY THE ADRESS
;CONTAINED IN THE LOCATION ADRESS.THE LOWER NIBBLE OF THE "ADRESS"
;CONTAINS THE NMC9306 REGISTER ADDRESS. THE UPPRE NIBLE SHOULD BE
;SET ZERO.
;
;

ERASE:  LD      A,ADRESS
	OR      A,#0C0
	X       A,SNDBUF
	LD      FLAGS,#05       ;DELAY BEFORE CS GOES LOW
	JSR     INIT
	RET
;
;THIS ROUTINE ENABLS PROGRAMMING TO COP 494.PROGRAMMING MUST BE
;PRECEDED ONCE BY PROGRAMMING ENABLE (EWEN).
;
EWEN:   LD      SNDBUF,#030
	LD      FLAGS,#00
	JSR     INIT
	RET
;
;THIS ROUTINE DISABLES PROGRAMMING OF NMC9306.
;
EWDS:   LD      SNDBUF,#00
	LD      FLAGS,#00
	JSR     INIT
	RET
;
;THIS RUOTINE ERASES ALL REGISTERS OF NMC9306.
;
ERAL:   LD      SNDBUF,#020
	LD      FLAGS,#05
	JSR     INIT
	RET
;
;THIS RUOTINE READS THE CONTENTS OF THE NMC9306 REGISTER.THE NMC9306
;ADDRESS IS SPECIFID IN THE LOWER NIBBLE OF LOCATION "ADDRESS".THE UPPER
;NIBBBLE SHOULD BE SET TO ZERO.THE 16-BIT CONTENTS OF NMC9306 REGISTER ARE
;STORED IN RDATL AND RDATH.
;
READ:   LD      A,ADRESS
	OR      A,#080
	X       A,SNDBUF
	LD      FLAGS,#01
	JSR     INIT
	RET
;
;THIS WRITES A 16-BIT VALUE STORED IN WDATL AND WDADTH TO THE VOP 494
;REGISTER WHOSE ADDRESS IS CONTAINED IN THE LOWER NIBBLE OF THE
;LOCATION "ADRESS".THE UPPER NIBBLE OF THE ADDRES SHOULD BE SET TO ZERO.
;
WRITE:  LD      A,ADRESS
	OR      A,#040
	X       A,SNDBUF
	LD      FLAGS,#03
	JSR     INIT
	RET
;
;THIS ROTINE SENDS OUT THE START BIT AND COMMAND BYTE.IT ALSO
;DECIPHERS THE CONTENTS OF THE ;FLAG LOCATION AND TAKES A DECISION
;REGARDING WRITE,READ OR RETURN TO THE CALLING RUOTINE.
;
INIT:   SBIT    2,PORTGD        ;SET CHIP SELECT HIGH
	LD      SIOR,#001       ;LOAD SIOR WHITH START BIT
	SBIT    BUSY,[B]        ;SEND OUT THE START BIT
PUNT1: IFBIT    BUSY,[B]
	JP      PUNT1
	LD      A,SNDBUF
	X       A,[X]         ; LOAD SIOR WITH COMMAND BYTE
	SBIT    BUSY,[B]      ; SEND OUT COMMAND BYTE
PUNT2:  IFBIT   BUSY,[B]
	JP      PUNT2
	IFBIT   0,FLAGS         ;ANY FURTHER PROCESSING ?
	JP      NOTDON          ;YES
	RBIT    2,PORTGD        ;NO, RESET CS AND RETURN
	RET
;
;               DO EXTRA PROCESSING HERE:
;
NOTDON: IFBIT   1,FLAGS         ;READ OR WRITE ?
	JP      WR494           ;JMP TO WRITE ROUTINE
	IFBIT   2,FLAGS         ;
	JMP     TMOUT
	LD      SIOR,#000       ;NO, DO READ NMC9306
	RBIT    GIE,PSW         ;Interrupts sperren
	SBIT    BUSY,PSW        ;DUMMY CLOCK TO READ ZERO
	NOP
	NOP
	RBIT    BUSY,[B]
	SBIT    GIE,PSW         ;Interrupts erm”glichen
	SBIT    BUSY,[B]
PUNT3:  IFBIT   BUSY,[B]
	JP      PUNT3
	X       A,[X]
	SBIT    BUSY,[B]
	X       A,RDATH
PUNT4:  IFBIT   BUSY,[B]
	JP      PUNT4
	LD      A,[X]
	X       A,RDATL
	RBIT    2,PORTGD
	RET
;
WR494:  LD      A,WDATH
	X       A,[X]
	SBIT    BUSY,[B]
PUNT5:  IFBIT   BUSY,[B]
	JP      PUNT5
	LD      A,WDATL
	X       A,[X]
	SBIT    BUSY,[B]
PUNT6:  IFBIT   BUSY,[B]
	JP      PUNT6
	RBIT    2,PORTGD
	JMP     TOUT


;************************************************
;*              Verz”gerungsroutine             *
;************************************************

TMOUT:  RBIT    2,PORTGD
TOUT:   LD      DLYH,#012H
WAIT:   LD      DLYL,#0FFH
WAIT1:  DRSZ    DLYL
	JP      WAIT1
	DRSZ    DLYH
	JP      WAIT
	RET


.end UNI


