;************************************************************************
;*			RC5 - Modellbaufernsteuerung			*
;*				Version 1				*
;************************************************************************

;Instruction cycle = 1us (10Mhz Quarz)
;Pinbelegung des COP8782:
;	G0 = RC5 Code vom Infrarotempf„nger	L0 = LED
;	G1 =					L1 =
;	G2 =					L2 =
;	G3 = Pulsausgang fr Servosteuerung	L3 =
;	G4 = Codierung fr Adresse		L4 =
;	G5 =					L5 =
;	G6 =					L6 = Brckensteuerung
;	G7 = Quarz				L7 = Brckensteuerung

.incld cop880.inc
.sect main,rom,abs=0

;Rambelegung

ASICHER 	= 00H
BSICHER 	= 01H
XSICHER 	= 02H
STATUS		= 03H	;0 = Toggle
PULSHIGHL	= 04H	;Dauer der Highphase des Pulses zur Ansteuerung des Servos 	(Lowbyte)
PULSHIGHH	= 05H	;				#				(Highbyte
PULSLOWL	= 06H	;Dauer der Lowphase des Pulses zur Ansteuerung des Servos 	(Lowbyte)
PULSLOWH	= 07H	;				#				(Highbyte)
R4		= 08H
R5		= 09H
PSWSICHER	= 0AH
TEMP		= 0BH
TEMP1		= 0CH

R6		= 0F0H
R7		= 0F1H

;************************************************
;*		Initialisierungsphase		*
;************************************************
RC5:
	LD      B,#0FDH         ;Clear Ram
RAM:    LD      [B],#0          ;
	DRSZ    B               ;
	JP      RAM             ;
	LD      0,#0            ;
	LD      PORTLC,#0FFH    ;L1-L7 Pins als Ausgang Low
	LD      PORTLD,#1       ;L0 High (LED aus)
	LD      PORTCC,#0FFH    ;Alle C-Pins als Ausgang Low
	LD      PORTCD,#0       ;
	LD      PORTGC,#B'01101110;G4 Eingang Pull up; Alle anderen Ausgang Low
	LD	PORTGD,#B'00010001;G0 Eingang ohne Pull up
	LD      SP,#06FH        ;Stackpointer auf oberste Ramadresse
	LD	PULSHIGHL,#0DCH	;Startbedingung fr Servo: 1.5ms High alle 20ms
	LD	PULSHIGHH,#005H	;
	LD	PULSLOWL,#044H	;
	LD	PULSLOWH,#048H	;
	LD      B,#TMRLO        ;Timer vorbesetzen
	LD      [B+],#0DCH      ;
	LD      [B+],#005H      ;
	LD      [B+],#044H      ;Reloadregister vorbesetzen
	LD      [B],#048H       ;
	SBIT	0,STATUS	;SBIT Toggle(0),Status
	SBIT    7,CNTRL         ;Timer mit Autoreload und Toggle des G3-Pins
	SBIT	5,CNTRL		;
	LD      PSW,#011H       ;Enable Timer-Interrupt
				;Enable General-Interrupt
	SBIT    4,CNTRL         ;Timer anschalten
	JP	LOOP


.=0FFH

;************************************************
;*              Interrupt                       *
;************************************************

	X       A,ASICHER       ;
	RBIT	TPND,PSW	;Timer Pending Flag l”schen
	IFBIT	0,STATUS	;IF Bit Toggle(0),Status
	JP	TIME0		;
	JP	TIME1		;
TIME0:	RBIT	0,STATUS	;THEN RBIT Toggle(0),Status
	LD	A,PULSLOWL	;     Lange Lowphase ins Autoreloadregister
	X	A,0ECH		;
	LD	A,PULSLOWH	;
	X	A,0EDH		;
	JP	TIMEE		;
TIME1:	SBIT	0,STATUS	;ELSE SBIT Toggle(0),Status
	LD	A,PULSHIGHL	;     Kurze Highphase ins Autoreloadregister
	X	A,0ECH		;
	LD	A,PULSHIGHH	;
	X	A,0EDH		;
				;ENDIF
TIMEE:	LD      A,ASICHER       ;
	RETI

;************************************************
;*		Hauptprogramm			*
;************************************************

LOOP:	LD	R6,#0
COUNT:	LD	A,PORTGP
	AND	A,#1
	IFEQ	A,#0
	JP	LOOP
	NOP	
	NOP
	DRSZ	R6
	JP	COUNT
WORD:	LD	R7,#13		; Bitz„hler
	LD	R5,#0           ; RC5 Kommando und Adressbytes l”schen
	LD	R4,#0           ;
HIGHBIT:IFBIT	0,PORTGP	;Aufs Lowbit warten
	JP	HIGHBIT
TEST:	LD	A,#165
	JSR	WAIT
NXTBIT:
	LD	A,PORTGP	;1. mal einlesen
	AND	A,#1		;
	X	A,R6		;
	LD	A,#110		;~900us Wartezeit
	JSR	WAIT		;
	LD	A,PORTGP	;2. mal einlesen
	AND	A,#1		;
	SC			;
	SUBC    A,R6		;Beide eingelesene Werte drfen nicht bereinstimmen!
	IFEQ	A,#0		;
	JP	LOOP		;
	LD	A,R4		;Bitwert (Carry) in R4 und R5 durch Rotation einschreiben
	RRC	A		;		#
	X	A,R4		;		#
	LD	A,R5		;		#
	RRC	A		;		#
	X	A,R5		;		#
	LD	A,#100		;nochmal warten
	JSR	WAIT		;
	DRSZ	R7		;und das n„chste Bit einlesen
	JP	NXTBIT
				;Ab jetzt sind alle Bits eingelesen
SHIFT:	LD	A,R4		;Zun„chst Kommando extrahieren (6 Bits)
	X	A,TEMP		;Alle Bits liegen invertiert und in der falschen
	LD	R4,#0		;Reihenfolge vor und mssen deshalb erstmal korrekt
	LD	A,R5		;in R4 und R5 einsortiert werden!
	X	A,TEMP1
	LD	R5,#0
	IFBIT	7,TEMP
	JP	BIT1
	SBIT	0,R4
BIT1:	IFBIT	6,TEMP
	JP	BIT2
	SBIT	1,R4
BIT2:	IFBIT	5,TEMP
	JP	BIT3
	SBIT	2,R4
BIT3:	IFBIT	4,TEMP
	JP	BIT4
	SBIT	3,R4
BIT4:	IFBIT	3,TEMP
	JP	BIT5
	SBIT	4,R4
BIT5:	IFBIT	2,TEMP
	JP	BIT6
	SBIT	5,R4
BIT6:	IFBIT	1,TEMP		;Jetzt die Adresse extrahieren (5 Bits)
	JP	BIT7
	SBIT	0,R5
BIT7:	IFBIT	0,TEMP
	JP	BIT8
	SBIT	1,R5
BIT8:	IFBIT	7,TEMP1
	JP	BIT9
	SBIT	2,R5
BIT9:	IFBIT	6,TEMP1
	JP	BIT10
	SBIT	3,R5
BIT10:	IFBIT	5,TEMP1
	JP	BITTE
	SBIT	4,R5
BITTE:	JSR	LED		;CALL 'Led'

;************************************************
;*	Adressencodierung auswerten		*
;************************************************
	
	IFBIT	4,PORTGP	;Offene Brcke = keine Adresse bercksichtigen
	JP	WEITER		;
	LD	A,R5		;Geschlossene Brcke = nur bei Adresse von Tuner weitermachen
	IFEQ	A,#017H		;Tuner = Adresse 17
	JP	WEITER		;
ERROR:	LD	R7,#10		;Bei falscher Adresse LED 10x aufblitzen lassen
ERR2:	LD	R6,#20		;	#
ERR1:	LD	A,#255		;	#
	JSR	WAIT		;	#
	JSR	WAIT		;	#
	DRSZ	R6		;	#
	JP	ERR1		;	#
	JSR	LED		;	#
	DRSZ	R7		;	#
	JP	ERR2		;
	JP	EXIT		;

;****************************************************************
;*		Auswerten der gesendeten Information		*
;*		R4 = Kommando					*
;*		R5 = Adresse					*
;****************************************************************

WEITER:	LD	A,R4 		;
	IFEQ	A,#010H		;IF Kommando = 010H (Volume-)
	JP	KOM0		;
	JP	KOM1		;
KOM0:	JSR	SERVOPLUS	;THEN CALL 'Servoplus'
	JP	EXIT		;
KOM1:	IFEQ	A,#011H		;ELSE IF Kommando = 011H (Taste Volume+)
	JP	KOM11		;
	JP	KOM2		;
KOM11:	JSR	SERVOMINUS	;     THEN CALL 'Servominus'
	JP	EXIT		;
KOM2:	IFEQ	A,#01		;     ELSE IF Kommando = 1 (Taste 1)
	JP	KOM22		;
	JP	KOM3		;
KOM22:	JSR	MOTORSTOP	;          THEN CALL 'Motorstop'
	JP	EXIT		;
KOM3:	IFEQ	A,#2		;          ELSE IF Kommando = 2 (Taste 2)
	JP	KOM33		;
	JP	KOM4		;
KOM33:	JSR	MOTORVOR	;               THEN CALL 'Motorvor'
	JP	EXIT		;
KOM4:	IFEQ	A,#3		;               ELSE IF Kommando = 3 (Taste 3)
	JP	KOM44		;
	JP	EXIT		;
KOM44:	JSR	MOTORRUECK	;                    THEN CALL 'Motorrueck'
				;                    ENDIF
				;               ENDIF
				;          ENDIF
				;     ENDIF
EXIT:				;ENDIF
	JP	LOOP            ;...und wieder auf das n„chste Kommando warten

;************************************************
;*	LED bei gltigem Befehl ansteuern	*
;************************************************

LED:	RBIT	0,PORTLD	;LED kurz aufblitzen lassen
	LD	A,#127		;	#
	JSR	WAIT		;	#
	SBIT	0,PORTLD	;	#
	RET			;

;************************************************
;*	Servozeit erh”hen			*
;************************************************
;Servozeit wird um 50us pro Befehl erh”ht
SERVOPLUS:
	LD	A,PULSHIGHL	;Grenzwertberprfung fr 2ms (Maximalwert)
	IFEQ	A,#0D0H		;
	JP	PLU1		;
	JP	PLUS1		;
PLU1:	LD	A,PULSHIGHH	;
	IFEQ	A,#07		;
	RET			;		
PLUS1:	RC			;
	RBIT	4,CNTRL		;Timer stoppen
	LD	A,PULSHIGHL	;Highphase verl„ngern
        ADC	A,#50		;	#
        X	A,PULSHIGHL	;	#
        LD	A,PULSHIGHH	;	#
        ADC	A,#0		;	#
        X	A,PULSHIGHH	;	#
	SC			;
        LD	A,PULSLOWL	;und Lowphase entsprechend verkrzen
        SUBC    A,#50		;	#
        X	A,PULSLOWL	;	#
        LD	A,PULSLOWH	;	#
        SUBC    A,#0		;	#
        X	A,PULSLOWH	;	#
	SBIT	4,CNTRL		;Timer wieder anschalten
	RET

;************************************************
;*	Servozeit erniedrigen			*
;************************************************
;Servozeit wird um 50us pro Befehl erniedrigt
SERVOMINUS:
	LD	A,PULSHIGHL	;Grenzwertberprfung fr 1ms (Minimalwert)
	IFEQ	A,#0E8H		;
	JP	MINU1		;
	JP	MINUS1		;
MINU1:	LD	A,PULSHIGHH	;
	IFEQ	A,#03H		;
	RET			;
MINUS1:	SC			;
	RBIT	4,CNTRL		;Timer abschalten
        LD	A,PULSHIGHL	;Highphase des Pulses verkrzen
        SUBC    A,#50		;	#
        X	A,PULSHIGHL	;	#
        LD	A,PULSHIGHH	;	#
        SUBC    A,#0		;	#
        X	A,PULSHIGHH	;	#
	RC			;
        LD	A,PULSLOWL	;und Lowphase entsprechend verl„ngern
        ADC	A,#50		;	#
        X	A,PULSLOWL	;	#
        LD	A,PULSLOWH	;	#
        ADC	A,#0		;	#
        X	A,PULSLOWH	;	#
	SBIT	4,CNTRL		;Timer anschalten
        RET

;************************************************
;*	Motor ausschalten			*
;************************************************

MOTORSTOP:
	RBIT	7,PORTLD	;Brcke abschalten
	RBIT	6,PORTLD	;	#
	RET

;************************************************
;*	Motor vorw„rts schalten			*
;************************************************

MOTORVOR:
	RBIT	7,PORTLD	;
	SBIT	6,PORTLD	;
	RET

;************************************************
;*	Motor rckw„rts schalten		*
;************************************************

MOTORRUECK:
	RBIT	6,PORTLD	;
	SBIT	7,PORTLD	;
	RET

;************************************************
;*		Warteschleife      		*
;************************************************
;Zeit = Accu * 8us
WAIT:	NOP		;
	DECA		;
	IFEQ	A,#0	;
	RET		;
	JP	WAIT	;
   
.END RC5
