---------------------------------------------------------------------------------------------------------------------------- -- Описание: Прошивка микросхемы 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;