class_name yems_dev extends Node


class InDev:
    var id: int						## Идентификатор индекс устройства.
    var dev_name: String			## Имя подключаемого комплекса.
    var connector: String			## Номер разъёма в приборе.
    var delay: float				## Задержка фронта импульса.
    var offset: float				## Смещение фронта импульса.
    var state: int					## Состояние входа.
    var freq: int					## Предполагаемая частота на которой работает комплекс.
    var ports_data: Dictionary 		## Словарь состояния портов устройства.
    var tbl_row_id: int				## Индекс устройства в таблице.
    var out_dots: Array				## Список выходных устройств в порядке, как в таблице и точки матрицы.
    var connect_devs: Dictionary 	## Список присоединённых устройств.
    var board: String				## Плата в которой находится устройство.
    var isa_addr: int               ## Адрес устройства на шине isa

    func _init(dev_id : int, params : Array, row_id : int, base_addr: int):
        id = dev_id
        dev_name = String(params[0])
        connector = String(params[1])
        delay = float(params[2])
        offset = float(params[3])
        tbl_row_id = row_id
        isa_addr = base_addr
        ports_data[isa_addr + 4] = 0xFFFF
        ports_data[isa_addr + 6] = 0xFFFF
        ports_data[isa_addr + 8] = 0xFFFF
        ports_data[isa_addr + 10] = 0xFFFF

## Устанавливает задержки переднего и заднего фронта из данных портов
    func set_delay_offset():
        delay = float(ports_data[isa_addr + 10] & 0x003F)/10
        offset = float((ports_data[isa_addr + 10] >> 6) & 0x01FF)/10

## Устанавливает задержку переднего фронта в порт
    func set_delay(val):
        delay = val
        var bin_val = int(val * 10)
        ports_data[isa_addr + 10] = tools.set_bits(ports_data[isa_addr + 10], bin_val, 0x003F)

## Устанавливает задержку заднего фронта в порт
    func set_offset(val):
        offset = val
        var bin_val = int(val * 10)
        ports_data[isa_addr + 10] = tools.set_bits(ports_data[isa_addr + 10], (bin_val << 6), 0x7FC0)

class OutDev extends InDev:
    var mode: int			## Режим работы выхода.
    var btns_state: = Dictionary()

    func set_default_mode(): mode = 0

## Устанавливает режим работы выхода из порта
    func set_mode():
        if (ports_data[isa_addr + 8] >> 13) & 1:
            mode = 1
        elif (ports_data[isa_addr + 8] >> 14) & 1:
            mode = 2
        elif (ports_data[isa_addr + 8] >> 15) & 1:
            mode = 3
        else:
            mode = 0

## Устанавливает список соединений из портов
    func set_btns_state():
        var data = ports_data[isa_addr + 4] | (ports_data[isa_addr + 6] << 16) | ((ports_data[isa_addr + 8] & 0x3f) << 32)
        for i in range(yemsconsts.NUM_INPUT):
            btns_state[i+1] = bool((data >> i) & 1)

## Устанавливает соединение и записывает в порт
    func set_dot(i_dev, val):
        if btns_state.has(i_dev):
            btns_state[i_dev] = val
            var data = 0
            for i in range(yemsconsts.NUM_INPUT):
                data = data | (int(btns_state[i+1]) << i)
            ports_data[isa_addr + 4] = data & 0xffff
            ports_data[isa_addr + 6] = (data >> 16) & 0xffff
            ports_data[isa_addr + 8] = tools.set_bits(ports_data[isa_addr + 8], ((data >> 32) & 0x3f), 0x003F)

## Записывает в порт режим работы выхода
    func set_sw_mode(o_state):
        mode = o_state
        if mode == 0:
            ports_data[isa_addr + 8] = tools.set_bits(ports_data[isa_addr + 8], 0x0000, 0xE000)
        elif mode == 1:
            ports_data[isa_addr + 8] = tools.set_bits(ports_data[isa_addr + 8], 0x2000, 0xE000)
        elif mode == 2:
            ports_data[isa_addr + 8] = tools.set_bits(ports_data[isa_addr + 8], 0x4000, 0xE000)
        elif mode == 3:
            ports_data[isa_addr + 8] = tools.set_bits(ports_data[isa_addr + 8], 0x8000, 0xE000)
