ZXM_Jasper/module_cpld.tdf

903 lines
39 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

----------------------------------------------------------------------------------------------------------------------------
-- Описание: Прошивка микросхемы CPLD DD1 (модуль EPM3256AQC208_IGP1 Вариант 2)
-- Проект: ZXM-Jasper
-- Автор: Тарасов М.Н. (Mick)
-- Тип CPLD: EPM3256AQC208
-- Версия: v1.00 - 01 декабря 2017
----------------------------------------------------------------------------------------------------------------------------
TITLE "ZXM-Jasper System Array Logic";
FUNCTION 2mux1 (a, b, sel) RETURNS (y);
SUBDESIGN MODULE_CPLD
(
-- Входная тактовая частота CLK
CLK_14MHZ : INPUT;
-- Сигналы управления RAM памятью
MA[18..0] : OUTPUT;
MD[7..0] : BIDIR;
WR_RAM : OUTPUT;
CS_RAML : OUTPUT;
CS_RAMH : OUTPUT;
-- Выходные сигналы видео формирователя
VD[7..0] : OUTPUT;
HS : OUTPUT;
VS : OUTPUT;
GI : OUTPUT;
-- Сигналы управления ROM памятью
ROM_A14 : OUTPUT;
ROM_A15 : OUTPUT;
ROM_A16 : OUTPUT;
ROM_A17 : OUTPUT;
ROM_A18 : OUTPUT;
RD_ROM : OUTPUT;
WR_ROM : OUTPUT;
CS_ROM : OUTPUT;
-- Сигналы управления с CPU
CA[15..0] : INPUT;
CD[7..0] : BIDIR;
C_CLK : OUTPUT;
C_IORQ : INPUT;
C_MREQ : INPUT;
C_M1 : INPUT;
C_RD : INPUT;
C_WR : INPUT;
C_RFSH : INPUT;
-- Общие сигналы
C_RESET : INPUT;
C_IORQGE : INPUT;
C_INT : OUTPUT;
C_NMI : OUTPUT;
C_BLK : INPUT; -- просто декларируем (не используется)
C_BUSRQ : INPUT; -- просто декларируем (не используется)
C_WAIT : INPUT; -- просто декларируем (не используется)
C_IODOS : INPUT; -- просто декларируем (не используется)
C_DOS : OUTPUT;
-- Сигналы взаимодействия c AVR
C_MAGIC : INPUT;
C_PNT : INPUT;
--C_TURBO : INPUT;
-- Сигналы AY-3-8912
AYCLK : OUTPUT;
BC1 : OUTPUT;
BDIR : OUTPUT;
-- Сигналы порта FE
TAPE_IN : INPUT;
TAPE_OUT : OUTPUT;
BEEP : OUTPUT;
-- Сигналы выбора джойстика
RD_1F : OUTPUT;
-- Скандаблер
PA[14..0] : OUTPUT; -- адреса знакомест
VWR : OUTPUT; -- сигнал записи в видеобуфер
PD[7..0] : BIDIR; -- данные
-- Сигналы клавиатуры
KBD_CS : INPUT;
KBD_CLK : INPUT;
KBD_DI : INPUT
)
VARIABLE
Sync_count[2..0] : DFF; -- 3-х разрядный счетчик, сигналы TI, H0, H1
CLKZ : NODE; -- частота процессора
H0M : NODE; -- частота селектора памяти
H1M : NODE; -- частота селектора памяти
VCLK : NODE; -- опорная частота видеосчетчиков
HSync_count[6..0] : DFF; -- 7-и разрядный счетчик строчной разверкти, сигналы H2, H3..H8
HReset : NODE; -- сброс счетчиков строчной развертки
HBlank : NODE; -- сигнал гашения видеосигнала строчный
HBlank1 : NODE; -- сигнал гашения видеосигнала строчный
HBlank2 : NODE; -- сигнал гашения видеосигнала строчный
HBlank3 : DFF; -- сигнал гашения видеосигнала строчный
HBorder : NODE; -- сигнал строчного бордера
HSync : DFF; -- строчный синхроимпульс
HSync1 : DFF; -- синхроимпульс счета кадровых счетчиков
VSync_count[8..0] : DFF; -- 9-и разрядный счетчик кадровый развертки, сигналы V0..V8
VReset : NODE; --сброс счетчиков кадровой развертки
VSync : DFF; -- кадровый синхроимпульс
VBorder : NODE; -- сигнал кадрового бордера
Border_sync : DFF; -- строб бордера
Int_sync : DFF; -- строб прерывания
Int_count[3..0] : DFF; -- 4-и разрядный счетчик длительности прерывания
Flash_count[4..0] : DFF; -- 5-и разрядный счетчик мерцания, сигнал FLASH
REG_rddata[7..0] : TRI; -- буфер чтения памяти
DATA_CPU[7..0] : TRI_STATE_NODE;
-- Сигналы управления памятью
WR_RAM : LCELL;
WR_Buf : LCELL; -- запись в буферный регистр
VA[4..0] : NODE; -- адрес видео памяти
RA[5..0] : NODE; -- адрес видео памяти
Sel_A45 : NODE; -- доступ к ОЗУ
Ram_sel : DFF;
Ram_write_r : DFFE; -- запись в ОЗУ
Ram_wrdata[7..0] : TRI; -- буфер записи в ОЗУ
Ram_buf[7..0] : DFF;
Ram_smx : NODE; -- страницы ОЗУ
RD_MEMORY : LCELL;
ROM_SEL : NODE;
-- Сигналы управления видеоформирователем
WRSCR : LCELL; -- сигнал защелкивания видеоинформации
Reg_inf[7..0] : DFF; -- регистр видеоинформации
Reg_pix[7..0] : DFF; -- регистр пикселей (промежуточный)
Reg_atr[7..0] : DFF; -- регистр цвета
Pix_inf : LCELL; -- видеоинформация
Reg_vid[5..0] : DFF; -- регистр видео выходной
ColourADR[3..0] : NODE;
-- Управляющие сигналы
IO_ENABLE : NODE; -- доступ к портам
IO_RD : LCELL; -- чтение из портов
IO_WR : LCELL; -- запись в порты
-- TR-DOS контроллер
Sel_code : NODE; -- выбор ПЗУ TRDOS
Sel_3dxx : NODE; -- выбор ПЗУ TRDOS
DOS_r : JKFF; -- выбор ПЗУ TRDOS
NMI_r : DFF; -- выбор ПЗУ TRDOS
DOS_En : LCELL; --доступ к контроллеру дисковода
-- Регистр порта xxFEh
WR_FE : LCELL;
Border_Color_r[2..0] : DFF;
Tape_r : DFF;
Beep_r : DFF;
-- Регистр порта 7FFDh
Sel_7FFD : NODE;
WR_7FFD : LCELL;
RAM0_Page_r[4..0] : DFF; -- основные страницы 128кб + доролнительные страницы выше 128кб (общий объём 1024)
SCR128_r : DFF; --экран в 4000h или C000h (3 - бит)
ROM128_r : DFF; -- 128 ПЗУ (4 - бит)
BLK_Port_r : DFF; -- блокировка записи в порт (5 - бит)
-- Скандаблер
VWR : LCELL;
VHReset : NODE;
VHBlank : NODE;
SHReset : NODE;
VWR_strobe : LCELL; -- запись в буфер
MUX_strobe : DFF; -- счетчик переключения буферов
MUX_data : LCELL; -- триггер конца строки
WHSync_count[6..0] : DFF; -- счетчик знакомест
VHSync_count[2..0] : DFF; -- счетчик знакомест
SHSync_count[2..0] : DFF; -- счетчик знакомест
VD_reg[5..0] : DFF; -- регистр видео
REG_wscan[7..0] : TRI;
RH : NODE;
-- интерфейс клавиатуры
RDFE_Sel : LCELL; -- выбор клавиатуры
KBD_save_en : NODE;
KBD_count[3..0] : DFFE;
KBD_shift_in[7..0] : DFF;
KBD_regA8[4..0] : DFFE;
KBD_regA9[4..0] : DFFE;
KBD_regA10[4..0] : DFFE;
KBD_regA11[4..0] : DFFE;
KBD_regA12[4..0] : DFFE;
KBD_regA13[4..0] : DFFE;
KBD_regA14[4..0] : DFFE;
KBD_regA15[4..0] : DFFE;
KBD_rddata[7..0] : TRI;
BEGIN
-----------------------------------------------------------------------------------
-- Синхрогенератор
------------------------------------------------------------------------------------
-- Clock frequency 14.000 MHz
-- "256 x 192 Screen"
-- Line frequency 31250 Hz
-- Field frequency 48 Hz
-- Sync polarity: H negative, V negative
-- Scan type: non interlaced.
------------------------------------------------------------------------------------
-- Системные сигналы
------------------------------------------------------------------------------------
Sync_count[].clk = CLK_14MHZ; -- Системные сигналы TI, H0, H1, 2
Sync_count[].d = Sync_count[].q+1;
VCLK = !(Sync_count[].q == B"111");
------------------------------------------------------------------------------------
-- Строчная развертка
------------------------------------------------------------------------------------
-- One line:
-- 32 pixels horizontal sync
-- 32 pixels back porch
-- 64 pixels left border
-- 256 pixels video
-- 64 pixels right border
------------------------------------------------------------------------------------
-- 448 pixels total per line
------------------------------------------------------------------------------------
-- Реализация
------------------------------------------------------------------------------------
-- 32 видимая часть
-- 8 правый бордер
-- 4 начало гасящего импульса
-- 4 строчный импульс
-- 8 левый бордер
-- =
-- 56 сброс счетчиков строчной развертки
------------------------------------------------------------------------------------
HSync_count[].clk = VCLK; -- Сигналы строчной развертки H3, H4, H5, H6, H7, BC
HSync_count[].d = HSync_count[].q+1;
HSync_count[].clrn = !HReset;
HReset = (HSync_count[6..4].q == B"111"); -- сброс счетчиков в конце второй строки VGA
HBorder = HSync_count[6].q; -- сигнал строчного бордера на второй строке VGA
HBlank1 = !(HSync_count[6..3].q == B"0101"); -- гасящий импульс на первой VGA строке
HBlank2 = !(HSync_count[6..3].q == B"1100"); -- гасящий импульс на второй VGA строке
HBlank = HBlank1 & HBlank2;
HSync.clk = VCLK;
HSync.d = HBlank # HSync_count[2].q;
HBlank3.clk = !(HSync_count[6..0].q ==B"1010000");
HBlank3.d = GND;
HBlank3.prn = !(HSync_count[6..0].q == B"1100101");
------------------------------------------------------------------------------------
-- Кадровая развертка
------------------------------------------------------------------------------------
-- One field:
-- 16 lines vertical sync = porch
-- 56 lines top border
-- 192 lines video
-- 48 lines bottom border
------------------------------------------------------------------------------------
-- 312 lines total per field
------------------------------------------------------------------------------------
-- Реализация
------------------------------------------------------------------------------------
-- 192 видимая часть
-- 48 нижний бордер
-- 16 кадровый импульс = гасящий импульс
-- 56 верхний бордер
-- =
-- 320 сброс счетчиков кадровой развертки
------------------------------------------------------------------------------------
HSync1.clk = VCLK;
HSync1.d = (HSync_count[6..0] == B"1001101");
VSync_count[].clk = HSync1.q; -- Сигналы кадровой развертки V0...V7
VSync_count[].d = VSync_count[].q+1;
VSync_count[].clrn = !VReset;
VReset = (VSync_count[8..3].q == B"101000");-- сброс на 320 строке
VBorder = VSync_count[8].q # (VSync_count[7].q & VSync_count[6].q); -- сигнал BK = V8 # (V7 & V6)
VSync.clk = VCLK;
VSync.d = !(VSync_count[8..4].q == B"01111");
------------------------------------------------------------------------------------
-- Сигнал строчной развертки
------------------------------------------------------------------------------------
HS = HSync.q;
------------------------------------------------------------------------------------
-- Сигнал кадровой развертки
------------------------------------------------------------------------------------
VS = VSync.q;
------------------------------------------------------------------------------------
-- Сигнал гашения (разрешает работу выходному регистру DD7 - КР1533ИР27)
------------------------------------------------------------------------------------
GI = GND;
------------------------------------------------------------------------------------
-- Счетчики мерцания
------------------------------------------------------------------------------------
Flash_count[].clk = !VSync.q; --Сигналы счетчиков мерцания BK/, FLASH
Flash_count[].d = Flash_count[].q+1;
------------------------------------------------------------------------------------
-- Строб бордера
------------------------------------------------------------------------------------
Border_sync.d = !(VBorder # HBorder);
Border_sync.clk = HSync_count[1].q;
------------------------------------------------------------------------------------
-- Счетчик длительности прерывания
------------------------------------------------------------------------------------
Int_count[].clk = VCLK;
Int_count[].d = Int_count[].q+1;
Int_count[].clrn = !Int_sync.q;
------------------------------------------------------------------------------------
-- Сигнал прерывания
-- Примечание: прерывание генерится с частотой 48Гц
------------------------------------------------------------------------------------
Int_sync.clk = !VSync.q; -- прерывание на 256 импульсе
Int_sync.d = GND;
Int_sync.prn = !(Int_count[3..0].q == B"1111");
------------------------------------------------------------------------------------
-- Сигнал прерывания
------------------------------------------------------------------------------------
C_INT = Int_sync.q;
-----------------------------------------------------------------------------------
-- Видеоформирователь
------------------------------------------------------------------------------------
-- Стробирующие сигналы захвата информации
------------------------------------------------------------------------------------
WRSCR = !(Sync_count[1].q & Sync_count[2].q & HSync_count[0].q);
------------------------------------------------------------------------------------
-- Сдвиговый регистр пикселей
------------------------------------------------------------------------------------
Reg_pix[].clk = HSync_count[0].q; -- сигналы H2
Reg_pix[].d = MD[];
------------------------------------------------------------------------------------
-- Сдвиговый регистр пикселей
------------------------------------------------------------------------------------
Reg_inf[].clk = Sync_count[0].q; -- сигнал 7MHZ
IF WRSCR !=0 THEN
Reg_inf[].d = (Reg_inf[7-1..0].q,GND);
ELSE
Reg_inf[].d = Reg_pix[];
END IF;
------------------------------------------------------------------------------------
-- Регистр атрибутов
------------------------------------------------------------------------------------
Reg_atr[].clk = WRSCR;
Reg_atr[].d = MD[];
------------------------------------------------------------------------------------
-- Мерцание знакоместа
------------------------------------------------------------------------------------
Pix_inf = Reg_inf[7].q $ (Flash_count[4].q & Reg_atr[7].q);
------------------------------------------------------------------------------------
-- Адреса палитры/цвета
------------------------------------------------------------------------------------
IF Border_sync.q ==0 THEN
ColourADR[0] = Border_Color_r[0].q;
ColourADR[1] = Border_Color_r[1].q;
ColourADR[2] = Border_Color_r[2].q;
ColourADR[3] = GND;
ELSE
IF Pix_inf ==0 THEN
ColourADR[0] = Reg_atr[3].q; --Blue
ColourADR[1] = Reg_atr[4].q; --Red
ColourADR[2] = Reg_atr[5].q; --Green
ColourADR[3] = Reg_atr[6].q; --Bright
ELSE
ColourADR[0] = Reg_atr[0].q; --Blue
ColourADR[1] = Reg_atr[1].q; --Red
ColourADR[2] = Reg_atr[2].q; --Green
ColourADR[3] = Reg_atr[6].q; --Bright
END IF;
END IF;
------------------------------------------------------------------------------------
-- Вывод видеоинформации
------------------------------------------------------------------------------------
Reg_vid[].clk = Sync_count[0].q; -- сигнал 7MHZ
Reg_vid[].clrn = HBlank3.q & VSync.q;
Reg_vid[0].d = ColourADR[0]; -- Blue0
Reg_vid[1].d = ColourADR[0] & ColourADR[3]; -- Blue1
Reg_vid[2].d = ColourADR[1]; -- Red0
Reg_vid[3].d = ColourADR[1] & ColourADR[3]; -- Red1
Reg_vid[4].d = ColourADR[2]; -- Green0
Reg_vid[5].d = ColourADR[2] & ColourADR[3]; -- Green1
------------------------------------------------------------------------------------
-- Сигнал формирование частоты процессора
-- Примечание: процессор на частоте 3,5МГц(NORMAL)
------------------------------------------------------------------------------------
H0M = Sync_count[1].q; -- H0
H1M = Sync_count[2].q; -- H1
CLKZ = !H0M;
C_CLK = CLKZ;
------------------------------------------------------------------------------------
-- Управление памятью RAM
------------------------------------------------------------------------------------
-- Сигнал записи в буферный регистр TI =1 и H0 =0
------------------------------------------------------------------------------------
WR_Buf = H0M & !H1M; -- сигнал WRBUF
------------------------------------------------------------------------------------
-- Запись в буферный регистр
------------------------------------------------------------------------------------
Ram_buf[].d = MD[];
Ram_buf[].clk = !WR_Buf;
------------------------------------------------------------------------------------
-- Сигнал мультиплексирования страниц ОЗУ
------------------------------------------------------------------------------------
Ram_smx = CA[15] and CA[14]; -- сигнал SMX = A15 & A14
------------------------------------------------------------------------------------
-- Выбор памяти ОЗУ
------------------------------------------------------------------------------------
Sel_A45 = CA[15] # CA[14]; -- сигнал A45 = A15 # A14 # BLK
------------------------------------------------------------------------------------
-- Сигнал записи в память
------------------------------------------------------------------------------------
Ram_write_r.d = Sel_A45 & !C_MREQ & C_RD & C_RFSH;
Ram_write_r.clrn = !H1M;
-- Ram_write_r.clk = !CLKZ;
-- Ram_write_r.prn = VCC;
Ram_write_r.ena = !CLKZ; --!Clk_reg[0].q; --память работает в турбо режиме 7МГц
Ram_write_r.clk = !CLK_14MHZ;
------------------------------------------------------------------------------------
-- Запись в память
------------------------------------------------------------------------------------
WR_RAM = !Ram_write_r.q;
Ram_wrdata[].in = CD[];
Ram_wrdata[].oe = Ram_write_r.q;
MD[] = Ram_wrdata[].out;
------------------------------------------------------------------------------------
-- Формирование адресов видеоконтроллера VА
------------------------------------------------------------------------------------
IF HSync_count[0].q ==0 THEN -- сигнал H2
VA[0] = VSync_count[0].q;
VA[1] = VSync_count[1].q;
VA[2] = VSync_count[2].q;
VA[3] = VSync_count[6].q;
VA[4] = VSync_count[7].q;
ELSE
VA[0] = VSync_count[6].q;
VA[1] = VSync_count[7].q;
VA[2] = GND;
VA[3] = VCC;
VA[4] = VCC;
END IF;
------------------------------------------------------------------------------------
-- Формирование адресов RА
------------------------------------------------------------------------------------
IF Ram_smx ==0 THEN -- выборк окна в адресах 0x000..0xBFFF
RA[0] = CA[14];
RA[1] = CA[15];
RA[2] = CA[14];
RA[3] = GND;
RA[4] = GND;
RA[5] = GND;
ELSE
RA[0] = RAM0_PAGE_r[0].q; -- сигнал Page0
RA[1] = RAM0_PAGE_r[1].q; -- сигнал Page1
RA[2] = RAM0_PAGE_r[2].q; -- сигнал Page2
RA[3] = RAM0_PAGE_r[3].q; -- сигнал Page3 256
RA[4] = RAM0_PAGE_r[4].q; -- сигнал Page4 512
RA[5] = BLK_Port_r.q; -- сигнал Page5 1024 (MA19*)
END IF;
-- RA[3] = GND;
-- RA[4] = GND;
-- RA[5] = GND;
------------------------------------------------------------------------------------
-- Формирование адресов и выбор микросхемы памяти
------------------------------------------------------------------------------------
IF H1M ==0 THEN
MA[13..0] = CA[13..0];
MA[18..14] = RA[4..0];
RAM_sel.d = RA[5];
ELSE
MA[4..0] = HSync_count[5..1]; -- сигналы H3...H7
MA[5] = VSync_count[3].q; -- сигнал V4
MA[6] = VSync_count[4].q; -- сигнал V5
MA[7] = VSync_count[5].q; -- сигнал V6
MA[12..8] = VA[4..0]; -- сигналы VA0...VA4
MA[13] = GND; -- сигнал 0
MA[14] = VCC; -- сигнал 1
MA[15] = SCR128_r.q; -- сигнал SCR128
MA[16] = VCC; -- сигнал 1
MA[17] = GND;
MA[18] = GND;
RAM_sel.d = GND;
END IF;
Ram_sel.clk = !CLK_14MHZ;
Ram_sel.clrn = C_RESET;
CS_RAML = Ram_sel.q; --0
CS_RAMH = !Ram_sel.q; --MA[19]* --1
-- CS_RAML = BLK_Port_r.q; --0
-- CS_RAMH = !BLK_Port_r.q; --MA[19]* --1
------------------------------------------------------------------------------------
-- Управление памятью ROM
------------------------------------------------------------------------------------
-- Формирование управляющих сигналов ROM памяти
------------------------------------------------------------------------------------
-- A14=0 A15=0 MONITOR
-- A14=1 A15=0 DOS
-- A14=0 A15=1 128
-- A14=1 A15=1 48
ROM_A14 = ROM128_r.q;-- # !DOS_En; -- сигнал RA14 = ROM128/ & !PRN;
ROM_A15 = !DOS_r.q; -- сигнал RA15 = DOS/ & !PRN;
ROM_A16 = GND;
ROM_A17 = GND;
ROM_A18 = GND;
------------------------------------------------------------------------------------
-- Сигнал выбора ПЗУ
------------------------------------------------------------------------------------
ROM_SEL = Sel_A45 # C_MREQ;
CS_ROM = GND;
------------------------------------------------------------------------------------
-- Сигнал чтения из ПЗУ
------------------------------------------------------------------------------------
RD_ROM = ROM_SEL # C_RD; -- сигнал RDROM/ = A45 # RD # MREQ
-----------------------------------------------------------------------------------
-- Сигнал записи в ПЗУ
------------------------------------------------------------------------------------
WR_ROM = VCC;
------------------------------------------------------------------------------------
-- Порты
------------------------------------------------------------------------------------
-- Сигнал управление портами
------------------------------------------------------------------------------------
IO_ENABLE = !C_M1 # C_IORQ # C_IORQGE;
------------------------------------------------------------------------------------
-- Сигнал чтения из портов
------------------------------------------------------------------------------------
IO_RD = IO_ENABLE # C_RD;
------------------------------------------------------------------------------------
-- Сигнал записи в порты
------------------------------------------------------------------------------------
IO_WR = IO_ENABLE # C_WR;
------------------------------------------------------------------------------------
-- Порт xx1Fh - Кемпстон джойстик 00011111b
-----------------------------------------------------------------------------------
RD_1F = CA[7] # !(CA[3..0] == B"1111") # !DOS_En # IO_RD;
------------------------------------------------------------------------------------
-- Порт xxFEh = 11111110b
------------------------------------------------------------------------------------
WR_FE = !(CA[3..0] == B"1110") # IO_WR;
Border_Color_r[2..0].d = CD[2..0];
Border_Color_r[2..0].clk = WR_FE;
Border_Color_r[2..0].clrn = C_RESET;
Tape_r.d = CD[3];
Tape_r.clk = WR_FE;
Tape_r.clrn = C_RESET;
Beep_r.d = CD[4];
Beep_r.clk = WR_FE;
Beep_r.clrn = C_RESET;
------------------------------------------------------------------------------------
-- Выход магнитофона
------------------------------------------------------------------------------------
TAPE_OUT = Tape_r.q;
------------------------------------------------------------------------------------
-- Выход звука
------------------------------------------------------------------------------------
BEEP = Beep_r.q;
------------------------------------------------------------------------------------
-- Селектор порта 7FFDh
-----------------------------------------------------------------------------------
Sel_7FFD = CA[15] # !(CA[7..0] == B"11111101") # IO_WR;
------------------------------------------------------------------------------------
-- Порт 7FFDh
-----------------------------------------------------------------------------------
WR_7FFD = Sel_7FFD # (BLK_Port_r.q & C_PNT);
RAM0_Page_r[2..0].d = CD[2..0];
RAM0_Page_r[2..0].clk = WR_7FFD;
RAM0_Page_r[2..0].clrn = C_RESET;
SCR128_r.d = CD[3];
SCR128_r.clk = WR_7FFD;
SCR128_r.clrn = C_RESET;
ROM128_r.d = CD[4];
ROM128_r.clk = WR_7FFD;
ROM128_r.clrn = C_RESET;
-- C_PNT
--
-- BLK_Port_r.d = CD[5];
-- BLK_Port_r.clk = WR_7FFD;
-- BLK_Port_r.clrn = C_RESET;
IF C_PNT ==0 THEN -- (mem=1024)
BLK_Port_r.d = CD[5]; -- сигнал Page5 1024
BLK_Port_r.clk = WR_7FFD;
BLK_Port_r.clrn = C_RESET;
RAM0_Page_r[4..3].d = CD[7..6]; -- сигнал Page3/4 256/512
RAM0_Page_r[4..3].clk = WR_7FFD;
RAM0_Page_r[4..3].clrn = C_RESET;
ELSE -- (mem = 128)
BLK_Port_r.d = CD[5];
BLK_Port_r.clk = WR_7FFD;
BLK_Port_r.clrn = C_RESET;
RAM0_Page_r[4..3].d = GND;
RAM0_Page_r[4..3].clk = WR_7FFD;
RAM0_Page_r[4..3].clrn = C_RESET;
END IF;
------------------------------------------------------------------------------------
-- Порты BFFDh и FFFDh
------------------------------------------------------------------------------------
BC1 = CA[15] & CA[14] & (CA[7..0] == B"11111101") & !IO_ENABLE;
BDIR = CA[15] & (CA[7..0] == B"11111101") & !IO_WR;
------------------------------------------------------------------------------------
-- Частота AY-3-8912
------------------------------------------------------------------------------------
AYCLK = Sync_count[2].q; -- сигнал H1 = 1,75МГц
------------------------------------------------------------------------------------
-- Доступ к контроллеру дисковода
------------------------------------------------------------------------------------
DOS_En = !DOS_r.q;
------------------------------------------------------------------------------------
-- TR-DOS контроллер
------------------------------------------------------------------------------------
-- Выбор окна ПЗУ
------------------------------------------------------------------------------------
Sel_code = C_M1 # C_MREQ;
Sel_3dxx = !(CA[15..8] == B"00111101") # !ROM128_r.q # Sel_code;
------------------------------------------------------------------------------------
-- Сигнал выбора контроллера NMI/
------------------------------------------------------------------------------------
NMI_r.d = C_MAGIC # !Sel_A45;
NMI_r.clk = Sel_code;
NMI_r.prn = Sel_3dxx & C_RESET;
------------------------------------------------------------------------------------
-- Сигнал NMI/
------------------------------------------------------------------------------------
C_NMI = NMI_r.q;
------------------------------------------------------------------------------------
-- Сигнал выбора контроллера DOS/
------------------------------------------------------------------------------------
---------------------------СИГНАЛ DOS НА ТМ7----------------------------------------
DOS_r.clrn = C_RESET;
DOS_r.j = !(Sel_3dxx & NMI_r.q);
DOS_r.clk = !CLK_14MHZ;
DOS_r.k = !(Sel_code # !Sel_A45);
---------------------------СИГНАЛ DOS НА ТМ2----------------------------------------
--DOS_r.prn = !(Sel_code # !Sel_A45) & C_RESET;
--DOS_r.clrn = (Sel_3dxx # Sel_code) & NMI_r.q;
--DOS_r.clk = vcc;
--DOS_r.d = vcc;
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
-- Сигнал DOS/
------------------------------------------------------------------------------------
C_DOS = !DOS_r.q; -- 0 = Активный ДОС
------------------------------------------------------------------------------------
-- Интерфейс клавиатуры
------------------------------------------------------------------------------------
-- Порт xxFEh - Клавиатура
------------------------------------------------------------------------------------
RDFE_Sel = !(CA[7..0] == B"11111110") # IO_RD;
-----------------------------------------------------------------------------------
-- Счетчик
------------------------------------------------------------------------------------
KBD_save_en = KBD_count[0].q # KBD_count[1].q # KBD_count[2].q # !KBD_count[3].q;
KBD_count[].clk = !KBD_CLK;
KBD_count[].ena = KBD_save_en;
KBD_count[].clrn = !KBD_CS;
KBD_count[].d = KBD_count[].q + 1;
------------------------------------------------------------------------------------
-- Входной сдвигающий регистр
------------------------------------------------------------------------------------
KBD_shift_in[].clk = KBD_CLK;
IF KBD_count[3].q ==0 THEN
KBD_shift_in[].d = (KBD_shift_in[7-1..0].q,KBD_DI);
ELSE
KBD_shift_in[].d = KBD_shift_in[].q;
END IF;
------------------------------------------------------------------------------------
-- Регистры клавиатуры
------------------------------------------------------------------------------------
KBD_regA8[4..0].d = KBD_shift_in[7..3].q;
KBD_regA9[4..0].d = KBD_shift_in[7..3].q;
KBD_regA10[4..0].d = KBD_shift_in[7..3].q;
KBD_regA11[4..0].d = KBD_shift_in[7..3].q;
KBD_regA12[4..0].d = KBD_shift_in[7..3].q;
KBD_regA13[4..0].d = KBD_shift_in[7..3].q;
KBD_regA14[4..0].d = KBD_shift_in[7..3].q;
KBD_regA15[4..0].d = KBD_shift_in[7..3].q;
KBD_regA8[].clk = KBD_CLK;
KBD_regA8[].ena = KBD_count[3].q & (KBD_shift_in[2..0].q == B"000");
KBD_regA8[].prn = C_RESET;
KBD_regA9[].clk = KBD_CLK;
KBD_regA9[].ena = KBD_count[3].q & (KBD_shift_in[2..0].q == B"001");
KBD_regA9[].prn = C_RESET;
KBD_regA10[].clk = KBD_CLK;
KBD_regA10[].ena = KBD_count[3].q & (KBD_shift_in[2..0].q == B"010");
KBD_regA10[].prn = C_RESET;
KBD_regA11[].clk = KBD_CLK;
KBD_regA11[].ena = KBD_count[3].q & (KBD_shift_in[2..0].q == B"011");
KBD_regA11[].prn = C_RESET;
KBD_regA12[].clk = KBD_CLK;
KBD_regA12[].ena = KBD_count[3].q & (KBD_shift_in[2..0].q == B"100");
KBD_regA12[].prn = C_RESET;
KBD_regA13[].clk = KBD_CLK;
KBD_regA13[].ena = KBD_count[3].q & (KBD_shift_in[2..0].q == B"101");
KBD_regA13[].prn = C_RESET;
KBD_regA14[].clk = KBD_CLK;
KBD_regA14[].ena = KBD_count[3].q & (KBD_shift_in[2..0].q == B"110");
KBD_regA14[].prn = C_RESET;
KBD_regA15[].clk = KBD_CLK;
KBD_regA15[].ena = KBD_count[3].q & (KBD_shift_in[2..0].q == B"111");
KBD_regA15[].prn = C_RESET;
------------------------------------------------------------------------------------
-- Выходной буфер
------------------------------------------------------------------------------------
KBD_rddata[0].in = (CA8 # KBD_regA8[0].q) & (CA9 # KBD_regA9[0].q) & (CA10 # KBD_regA10[0].q) & (CA11 # KBD_regA11[0].q) & (CA12 # KBD_regA12[0].q) & (CA13 # KBD_regA13[0].q) & (CA14 # KBD_regA14[0].q) & (CA15 # KBD_regA15[0].q);
KBD_rddata[1].in = (CA8 # KBD_regA8[1].q) & (CA9 # KBD_regA9[1].q) & (CA10 # KBD_regA10[1].q) & (CA11 # KBD_regA11[1].q) & (CA12 # KBD_regA12[1].q) & (CA13 # KBD_regA13[1].q) & (CA14 # KBD_regA14[1].q) & (CA15 # KBD_regA15[1].q);
KBD_rddata[2].in = (CA8 # KBD_regA8[2].q) & (CA9 # KBD_regA9[2].q) & (CA10 # KBD_regA10[2].q) & (CA11 # KBD_regA11[2].q) & (CA12 # KBD_regA12[2].q) & (CA13 # KBD_regA13[2].q) & (CA14 # KBD_regA14[2].q) & (CA15 # KBD_regA15[2].q);
KBD_rddata[3].in = (CA8 # KBD_regA8[3].q) & (CA9 # KBD_regA9[3].q) & (CA10 # KBD_regA10[3].q) & (CA11 # KBD_regA11[3].q) & (CA12 # KBD_regA12[3].q) & (CA13 # KBD_regA13[3].q) & (CA14 # KBD_regA14[3].q) & (CA15 # KBD_regA15[3].q);
KBD_rddata[4].in = (CA8 # KBD_regA8[4].q) & (CA9 # KBD_regA9[4].q) & (CA10 # KBD_regA10[4].q) & (CA11 # KBD_regA11[4].q) & (CA12 # KBD_regA12[4].q) & (CA13 # KBD_regA13[4].q) & (CA14 # KBD_regA14[4].q) & (CA15 # KBD_regA15[4].q);
KBD_rddata[5].in = VCC;
KBD_rddata[6].in = TAPE_IN;
KBD_rddata[7].in = VCC;
KBD_rddata[].oe = !RDFE_Sel;
DATA_CPU[] = KBD_rddata[].out;
------------------------------------------------------------------------------------
-- Чтение из буферного регистра
------------------------------------------------------------------------------------
RD_MEMORY = !Sel_A45 # C_MREQ # C_RD;
REG_rddata[].in = Ram_buf[].q;
REG_rddata[].oe = !RD_MEMORY;
DATA_CPU[] = REG_rddata[].out;
------------------------------------------------------------------------------------
-- Скандаблер на одну строку
------------------------------------------------------------------------------------
-- Счетчик адреса знакомест
------------------------------------------------------------------------------------
RH = HReset;
WHSync_count[].clk = CLK_14MHZ;
WHSync_count[].d = WHSync_count[].q+1;
WHSync_count[].clrn = !RH;
VHSync_count[].clk = !WHSync_count[5].q;
VHSync_count[].d = VHSync_count[].q+1;
VHSync_count[].clrn = VHReset & !RH;
SHSync_count[].clk = !WHSync_count[6].q;
SHSync_count[].d = SHSync_count[].q+1;
SHSync_count[].clrn = SHReset & !RH;
VHReset = !(VHSync_count[2..0].q ==B"111");
VHBlank = !(VHSync_count[2..0].q ==B"101");
SHReset = !(SHSync_count[2..0].q ==B"111");
------------------------------------------------------------------------------------
-- Строб строки знакомест
------------------------------------------------------------------------------------
MUX_data = !MUX_strobe.q;
MUX_strobe.clk = !(SHSync_count[2..0].q ==B"101");
MUX_strobe.d = MUX_data;
PA[9] = MUX_strobe.q $ VWR_strobe;
------------------------------------------------------------------------------------
-- Запись в буфер знакомест
------------------------------------------------------------------------------------
VWR_strobe = WHSync_count[0] & CLK_14MHZ; -- VWR_strobe : LCELL; -- запись в буфер
VWR = !VWR_strobe;
------------------------------------------------------------------------------------
-- Aдреса знакомест
-----------------------------------------------------------------------------------
IF VWR_strobe == 0 THEN
PA[0] = WHSync_count[0].q; -- 7MГЦ
PA[1] = WHSync_count[1].q; -- 3,5МГЦ
PA[2] = WHSync_count[2].q; -- 1,75МГЦ
PA[3] = WHSync_count[3].q; -- 0,875МГЦ
PA[4] = WHSync_count[4].q; -- 0,875МГЦ
PA[5] = WHSync_count[5].q; -- 0,4375МГЦ
PA[6] = VHSync_count[0].q; -- 0,21875МГЦ
PA[7] = VHSync_count[1].q; -- 0,109375МГЦ
PA[8] = VHSync_count[2].q; -- 0,0546875МГЦ
ELSE
PA[0] = WHSync_count[1].q; -- 3,5МГЦ
PA[1] = WHSync_count[2].q; -- 1,75МГЦ
PA[2] = WHSync_count[3].q; -- 0,875МГЦ
PA[3] = WHSync_count[4].q; -- 0,875МГЦ
PA[4] = WHSync_count[5].q; -- 0,4375МГЦ
PA[5] = WHSync_count[6].q; -- 0,21875МГЦ
PA[6] = SHSync_count[0].q; -- 0,109375МГЦ
PA[7] = SHSync_count[1].q; -- 0,0546875МГЦ
PA[8] = SHSync_count[2].q; -- 0,0546875МГЦ
END IF;
PA[10] = VCC;
PA[11] = VCC;
PA[12] = VCC;
PA[13] = VCC;
PA[14] = VCC;
------------------------------------------------------------------------------------
-- Строб видеоданных
------------------------------------------------------------------------------------
VD[0] = VD_reg[0].q; -- Blue0
VD[1] = VD_reg[1].q; -- Blue1
VD[2] = VD_reg[2].q; -- Red0
VD[3] = VD_reg[3].q; -- Red1
VD[4] = GND; -- Red2
VD[5] = VD_reg[4].q; -- Green0
VD[6] = VD_reg[5].q; -- Green1
VD[7] = GND; -- Green2
VD_reg[].clk = CLK_14MHZ;
VD_reg[5..0].d = PD[5..0];
VD_reg[].clrn = VHBlank;
REG_wscan[5..0].in = Reg_vid[5..0].q;
REG_wscan[7..6] = GND;
REG_wscan[].oe = VWR_strobe & CLK_14MHZ; -- good tv 12
PD[] = REG_wscan[].out;
------------------------------------------------------------------------------------
-- Взаимодействие с ШД процессора
------------------------------------------------------------------------------------
CD[] = DATA_CPU[];
--=====================================================================================
END;