
package cz.karry.dop.core;

import java.util.logging.Level;
import java.util.logging.Logger;


/**
 *
 * @author karry
 */

public class MemoryInterfaceOld implements 
        SignalListener,
        BusListener{

    private int dOutLo = 0;
    private int dOutHi = 0;
    private int dInLo = 0;
    private int dInHi = 0;
    private Core core;
    private Signal oeab;
    
    MemoryInterfaceOld(Core core){
        this.core = core;
        core.bus.addBusListener(this);
        
        try{
            oeab = core.getSignal(Core.OEAB);
            oeab.addSignalListener(this);
            
            core.getSignal(Core.CLK).addSignalListener(this);
            core.getSignal(Core.RESET).addSignalListener(this);
            
        } catch (Exception ex) {
            Logger.getLogger(Core.class.getName()).log(Level.SEVERE, null, ex);
        }
            
    }

    public void signalChangePerformed(Signal signal, boolean active) {
        if (signal.getName().equals(Core.OEAB)){
            if (active){
                core.ab_bus.setValue(core.bus.getValue());
            }else{
                core.ab_bus.setValue(0xffff);
            }
        }
        
        if (signal.getName().equals(Core.CLK)){
            try{
                if (active){
                    if (core.getSignal(Core.ECINL).isActive()){
                        dInLo = core.db_bus.getValue();
                    }
                    if (core.getSignal(Core.ECINH).isActive()){
                        dInHi = core.db_bus.getValue();
                    }
                    if (core.getSignal(Core.ECOUTWR).isActive()){
                        dOutHi = (core.bus.getValue() & 0xff00) >> 8;
                        dOutLo = (core.bus.getValue() & 0x00ff);
                    }
                }else{
                    if (core.getSignal(Core.OEWR).isActive()){
                        if (core.getSignal(Core.LH).isActive()){
                            core.db_bus.setValue(dOutHi);
                        }else{
                            core.db_bus.setValue(dOutLo);                            
                        }
                    }
                    if (core.getSignal(Core.OEINLH).isActive()){
                        // bus = DIH(7:0) DIL(7:0)
                        core.bus.setValue(dInLo | (dInHi << 8));
                    }else if(core.getSignal(Core.OEINSE).isActive()){
                        // Sign extended DIL
                        int extend = 0;
                        if ((dInLo & 0x80) == 0x80){
                            extend = 0xff00;
                        }
                        core.bus.setValue(dInLo | extend);
                    }else if(core.getSignal(Core.OEINZE).isActive()){
                        // Zero extended DIL
                        core.bus.setValue(dInLo);
                    }
                }
            } catch (Exception ex) {
                Logger.getLogger(Core.class.getName()).log(Level.SEVERE, null, ex);
            }
        }        
        
        if (signal.getName().equals(Core.RESET) && active){
            dOutLo = 0;
            dOutHi = 0;
            dInHi = 0;
            dInLo = 0;
        }
        
    }

    public void busChangePerformed(Bus bus, int value) {
        if (bus.getName().equals(Core.BUS) && (oeab != null) && oeab.isActive()){
            core.ab_bus.setValue(core.bus.getValue());
        }
    }
    
    public int getDo(){
        return dOutLo | (dOutHi << 8);
    }
    
    public int getDih() {
        return dInHi;
    }

    public int getDil() {
        return dInLo;
    }

}

