//
//  ENEPE - ENEPE No Es un Panel Electr'onico
//  (C) 2002 Antonio G'omez Muriana
//  (C) 2002 Miguel Montero G'amez
//
///////////////////////////////////////////////////

#include <iostream.h>
#include "sdlc++/defs.h"
#include "sdlc++/clock.h"
#include "sdlc++/gates.h"
#include "sdlc++/decods.h"
#include "sdlc++/muxs.h"
#include "sdlc++/latches.h"
#include "sdlc++/flip-flops.h"
#include "leds.h"
#include "user.h"
#include "roms.h"
#include "control.h"
#include "grafico.h"
#include "panel.h"

void main() {
	long iter = 0;
	
    WIRE GND5[5] = {GND, GND, GND, GND, GND};
	
	WIRE d[8], ck, 
		E=GND, E2, E3, E4,
		m_cab, m_cf, m_cs, m_ch,
		z_ca, z_cf, z_caf, z_ch, z_cafs, z_cafsh,
		ap[6], ap03[4], ap45[2], 
		ar[10], ar04[5], ar79[3],
		ca_out[5], cf_out[5], cs_out[5], ch_out[5];
	
	PANEL p;
	ROM_1K r;
	SENCOUNTER5 ca, cb, cf, cs, ch;
	AND and_ca, and_cf, and_ch,
		and_caf, and_cafs, and_cafsh;
	CONTROL ctrl_ab, ctrl_f, ctrl_s, ctrl_h;
	CLOCK clock(10);
	
	ginicializa();
	while (1) {
		clock.run(--iter,ck);
		
		if (E == VCC) {
			cout << "CA: " << WIRE2long(ca_out, 5) << " - ";
			cout << "CB: " << WIRE2long(ar04, 5) << " - ";
			cout << "CF: " << WIRE2long(cf_out, 5) << " - ";
			cout << "CS: " << WIRE2long(cs_out, 5) << " - ";
			cout << "CH: " << WIRE2long(ch_out, 5) << endl;
		}
		
		// Ejecutamos las rutinas de control de los contadores
		
		ctrl_ab.run(ck, E, m_cab, z_ca);
		ctrl_f.run(ck, E2, m_cf, z_caf);
		ctrl_s.run(ck, E3, m_cs, z_cafs);
		ctrl_h.run(ck, E4, m_ch, z_cafsh);
		
		
		// Contador CA - Selector de posici'on horizontal del panel: AP[0-3]
		// Comienza en: 00000
		// Detiene con: 01111
		// Incrementar: Reloj
		
		ca.run(ck, m_cab, ca_out, GND5);
		extend(ap03, 4, ca_out, 5);
		extend(ap, 6, ap03, 4);
		and_ca.run(z_ca, 4, ap03);
		
		
		// Contador CB - Selecctor de posici'on horizontal de la ROM: AR[0-4]
		// Comienza en: CS
		// Detiene cuando CA
		// Incrementar: Reloj
		
		cb.run(ck, m_cab, ar04, cs_out);
		extend(ar, 12, ar04, 5);
		
		
		// Contador CF - Seleccionar la Fila en el panel y la ROM: AP[4-5], AR[5-6]
		// Comienza en: 00000
		// Detiene con: 00011 y cuando CA
		// Incrementar: Fin de CA
		
		cf.run(E, m_cf, cf_out, GND5);
		extend(ap45, 2, cf_out, 5);
		copywire(ap, 4, ap45, 2);
		copywire(ar, 5, ap45, 2);
		and_cf.run(z_cf, 2, ap45);
		and_caf.run(z_caf, z_ca, z_cf);
		
		
		// Contador CS - Seleccionar el inicio del scroll
		// Comienza en: 00000
		// Detiene con: 10000 y cuando CF
		// Incrementar: Fin de CF
		
		cs.run(E2, m_cs, cs_out, GND5);
		and_cafs.run(z_cafs, z_caf, cs_out[4]);
		
		
		// Contador CH - Selecciona el anuncio a mostrar: AR[7-9] 
		// Comienza en: 00000
		// Detiene con: 00111 y cuando CS
		// Incrementar: Fin de CS
		
		ch.run(E3, m_ch, ch_out, GND5);
		extend(ar79, 3, ch_out, 5);
		copywire(ar, 7, ar79, 3);
		and_ch.run(z_ch, 3, ar79);
		and_cafsh.run(z_cafsh, z_cafs, z_ch);
		
		
		// Unimos los buses de datos y enviamos direcciones a la memoria y al panel
		
		r.run(E, d, ar);
		p.run(E, d, ap);
	}
}
