*****************************************************************
*  								*
* mcio24 - 	24 digitale IO-s fr Mikrocontroller		*
*								*
* System:	Xilinx XC9536 (VHDL)				*
*								*
* Version:	0.30						*
* Status:	einsetzbar					*
* 								*
* Autor:	Joerg Wolfram (joerg@jcwolfram.de)		*
*								*
* Lizenz:	GPL und FDL					*
*****************************************************************

Die Programme unterliegen der GPL (Gnu Public License) Version 2
oder spter und die Dokumentation der Hardware der FDL 
(Free Document License). Ich uebernehme ausdrcklich keinerlei
Haftung fr die Richtigkeit und Funktionsfhigket der im
Projekt enthaltenen Informationen. 


1.Hardware
==========
Das Projekt realisiert 24 digitale IO's fr Microcontroller. Da
aber 8 Portsignale bentigt werden, ist es eigentlich nur eine
Erweiterung um 16 IO's. Die Signale haben, equivalent zu den
Portpins der 51-er Mikrocontroller "Open-Kollektor"-Eigenschaften.
Bei einer logischen "1" sind sie hochohmig und knnen als Eingnge
benutzt werden. Dabei ist zu beachten, dass die CPLD's der
XC9000-er Serie keine internen Pullup-Widerstnde haben und diese
extern an die IO-Pins anzuschlieen sind. Das gilt natrlich nur
fr Anschlsse, die nicht durch die externe Beschaltung im
hochohmigen Zustand auf ein definiertes Potential (0 oder 1)
gezogen werden.
Pin 5 und Pin 6 mssen mit einer Brcke verbunden werden. Auf
diese Weise wird das Strobe-Signal fr die Ausgangsregister etwas
verzgert und es ist keine Vorhaltezeit fr die Datensignale
notwendig. Laufzeitunterschiede werden eliminiert und alle 8
Portsignale knnen gleichzeitig gesetzt werden, ohne dass es zu
Fehlinterpretungen kommen kann.   

Folgende Resourcen werden bei der realisierten Implementierung
belegt:

Makrozellen: 	36/36 	(100%)
Register:	24/36	(67%)
Produktterme:	103/180	(57%)
Signale:	72/72	(100%)
PIN's		34/34	(100%)

Globaler Takt:		1/3	2 als IO
Globaler Tristate:	0/2	2 als IO
Globaler Reset:		0/1

Inwieweit die Belegung der PIN's des CPLD geaendert werden kann,
habe ich nicht untersucht, die vorliegende Konfiguration ist aber
das Ergebnis verschiedener Optimierungen. 

Auf der "Controllerseite" sind folgende 8 Signale notwendig:

+-------------------------------+
| Signal	CPLD (PLCC44)	|
+-------------------------------+
|  PP0		11	 	|
|  PP1		 9	 	|
|  PP2		 8	 	|
|  PP3		 7	 	|
|  PP4		 4	 	|
|  PP5		 3	 	|
|  PP6		 2	 	|
|  PP7		 1		|
+-------------------------------+

Die 24 "Peripherie-Signale":   

+-------------------------------+
| Signal	CPLD (PLCC44)	|
+-------------------------------+
| I/O  0	12	 	|
| I/O  1	13	 	|
| I/O  2	14	 	|
| I/O  3	18	 	|
| I/O  4	19	 	|
| I/O  5	20	 	|
| I/O  6	22	 	|
| I/O  7	24	 	|
| I/O  8	25	 	|
| I/O  9	26	 	|
| I/O 10	27	 	|
| I/O 11	28	 	|
| I/O 12	29	 	|
| I/O 13	33	 	|
| I/O 14	34	 	|
| I/O 15	35	 	|
| I/O 16	36	 	|
| I/O 17	37	 	|
| I/O 18	38	 	|
| I/O 19	39	 	|
| I/O 20	40	 	|
| I/O 21	42	 	|
| I/O 22	43	 	|
| I/O 23	44	 	|
+-------------------------------+


2.Ansteuerung
=============
Die Ansteuerung erfolgt ber 8 Portpins des Mikrocontrollers.
Dabei dienen die untersten 4 Bits als bidirektionale Datenpins.
Die oberen 4 Bits stellen die Adresse dar. Wird das CPLD an Port P1 
eines AT89C2051 angeschlossen, mssen an die Portpins P0 und P1
Pullup-Widerstndevon ca. 10 KOhm angeschlossen werden.

Adressierung:

+------------------------------------------------------------------+
| PP7 PP6 PP5 PP4	Funktion PP0-PP3			   |
+------------------------------------------------------------------+
|  0   0   0   0	Schreiben nach Datennibble 0 (I/O 0...3)   |
|  0   0   0   1	Schreiben nach Datennibble 1 (I/O 4...7)   |
|  0   0   1   0	Schreiben nach Datennibble 2 (I/O 8...11)  |
|  0   0   1   1	Schreiben nach Datennibble 3 (I/O 12...15) |
|  0   1   0   0	Schreiben nach Datennibble 4 (I/O 16...19) |
|  0   1   0   1	Schreiben nach Datennibble 5 (I/O 20...23) |
|  0   1   1   0	keine Funktion				   |
|  0   1   1   1	keine Funktion				   |
|  1   0   0   0	Lesen von Datennibble 0 (I/O 0...3)        |
|  1   0   0   1	Lesen von Datennibble 1 (I/O 4...7)        |
|  1   0   1   0	Lesen von Datennibble 2 (I/O 8...11)  	   |
|  1   0   1   1	Lesen von Datennibble 3 (I/O 12...15) 	   |
|  1   1   0   0	Lesen von Datennibble 4 (I/O 16...19) 	   |
|  1   1   0   1	Lesen von Datennibble 5 (I/O 20...23) 	   |
|  1   1   1   0	keine Funktion (14)			   |
|  1   1   1   1	keine Funktion (15)			   |
+------------------------------------------------------------------+

Zwischen 2 Schreiboperationen muss immer eine Leseoperation statt-
finden oder die Codierung (15) augegeben werden. In der Praxis ist 
das aber meist nicht weiter nachteilig.


3.Beispielcode
==============	
Der 51-er Beispielcode zeigt, wie die (bitadressierbaren Datenbytes
2c-2e an die Ausgnge ausgegeben und die Eingnge in die Datenbytes
28-2a eingelesen werden, IO-Port ist P1. Die Routine bentigt 84
Taktzyklen.

iorout:	mov	p1,#$ff		;Vorsichtshalber alle Portpins auf 1
	mov	r0,#$2a		;Zeiger auf 3.Byte lesen
	mov	r1,#$2e		;Zeiger auf 3.Byte schreiben
	mov	r2,#6		;Schleifenzhler
ior1:	mov	a,@r1		;Byte lesen
	anl	a,$f0		;nur oberes Nibble
	orl	a,r2		;Adresse in die untersten 4 Bits
	dec	a		;Korrektur der Adresse
	swap	a		;Nibbles tauschen, damit Daten "unten"
	mov	p1,a		;Bits ausgeben
	setb	p1.7		;auf Lesen umschalten
	mov	a,p1		;Daten einlesen
	swap	a		;Daten in oberes Nibble
	xchd	a,@r0		;unteres Nibble holen
	mov	@r0,a		;Datum zurckschreiben
	dec	r2		;nchstniedrige Adresse
	mov	a,@r1		;Byte lesen
	swap	a		;Nibbles tauschen
	anl	a,$f0		;nur oberes Nibble			 
	orl	a,r2		;Adresse in die untersten 4 Bits
	dec	a		;Korrektur der Adresse
	swap	a		;Nibbles tauschen, damit Daten "unten"
	mov	p1,a		;Bits ausgeben
	setb	p1.7		;auf Lesen umschalten
	mov	a,p1		;Daten einlesen	
	xchd	a,@r0		;unteres Nibble schreiben
	dec	r0		;nchstniedriges Byte zum Lesen
	dec	r1		;nchstniedriges Byte zum Schreiben
	djnz	r2,ior1		;Schleife
	mov	p1,#$ff		;Vorsichtshalber alle Portpins auf 1
	ret			;und Schluss

