TITLE "Main"; PARAMETERS ( UPDATE = 1, -- 1 for UPDATE sheet MODE = "SPRINTER", -- or MODE = "SPECTRUM" NMI_ON = "OFF", -- "ON" - for use NMI SCREEN_OFF = "NOT_USE" -- "USE" - for use screen on/off ); INCLUDE "lpm_ram_dp"; INCLUDE "kbd"; --INCLUDE "video"; INCLUDE "video2"; INCLUDE "dcp"; --INCLUDE "dcp2"; INCLUDE "acceler"; INCLUDE "ay"; INCLUDE "mouse"; SUBDESIGN SP2_ACEX ( TG42 : INPUT; CLKZ1 : OUTPUT; /WAIT : BIDIR; /RESET : BIDIR; /M1 : INPUT; /RF : INPUT; /IO : INPUT; /WR : INPUT; /RD : INPUT; /HALT : INPUT; /MR : INPUT; A[15..0] : INPUT; D[7..0] : BIDIR; CS_ROM : OUTPUT; CS_CASH : OUTPUT; RA[17..14] : OUTPUT; V_CS[1..0] : OUTPUT; VA[15..0] : OUTPUT; V_WR[3..0] : OUTPUT; VD3[7..0] : BIDIR; VD2[7..0] : BIDIR; VD1[7..0] : BIDIR; VD0[7..0] : BIDIR; WR_COL : OUTPUT; DAC_DATA : OUTPUT; DAC_WS : OUTPUT; DAC_BCK : OUTPUT; MD[15..0] : BIDIR; MA[14..0] : OUTPUT; RAS_[1..0] : OUTPUT; CAS_[3..0] : OUTPUT; /WE : OUTPUT; XACS : OUTPUT; -- ROM_WE XA[3..0] : BIDIR; SXA : OUTPUT; RDXA : OUTPUT; WR_AWG : OUTPUT; RD_KMPS : OUTPUT; WR_DWG : OUTPUT; ) VARIABLE MS : MOUSE; KEYS : KBD; SVIDEO : VIDEO2 WITH (MODE=MODE); DECODE : DCP WITH (UPDATE=UPDATE); -- DECODE : DCP2; ACC : ACCELER; AY3 : AY; CBL : lpm_ram_dp WITH (lpm_width=16,lpm_widthad=8); CT[5..0] : NODE; CTH[5..0] : NODE; CTV[8..0] : NODE; CTF[6..0] : NODE; CLK42 : NODE; DD[7..0] : NODE; D_OUT : NODE; RD_RAM : NODE; MCA[1..0] : NODE; DVD3[7..0] : NODE; DVD2[7..0] : NODE; DVD1[7..0] : NODE; DVD0[7..0] : NODE; DMD[15..0] : NODE; DMDX[7..0] : NODE; COPY_SINC_H : NODE; COPY_SINC_V : NODE; START_UP : NODE; BLANK : NODE; -- WGA[1..0] : NODE; -- to MA[1..0] / WR_AWG^ -- FDD_C[2..0] : NODE; -- to MA[4..2] / WR_AWG^ -- HDD_C[3..0] : NODE; -- to MA[8..5] / WR_AWG^ -- HD_A[2..0] : NODE; -- to MA[11..9] / WR_AWG^ NMI_X : NODE; -- to MA12 / WR_AWG^ INT_X : NODE; -- to MA13 / WR_AWG^ TURBO : NODE; -- to MA14 / WR_AWG^ KBD_CX : NODE; -- to XA0 / WR_AWG^ KBD_DX : NODE; -- to XA1 / WR_AWG^ TAPE_OUT : NODE; -- to XA2 / WR_AWG^ KBD_CC : NODE; -- from XA0 / SXA=0 / RD_XA=0 KBD_DD : NODE; -- from XA1 / SXA=0 / RD_XA=0 TAPE_IN : NODE; -- from XA2 / SXA=0 / RD_XA=0 MOUSE_D : NODE; -- from XA3 / SXA=0 / RD_XA=0 FDD_CH : NODE; -- from XA0 / SXA=1 / RD_XA=0 FDD_W : NODE; -- from XA1 / SXA=1 / RD_XA=0 SINC_1 : NODE; -- from XA2 / SXA=1 / RD_XA=0 SINC_2 : NODE; -- from XA3 / SXA=1 / RD_XA=0 SINC_1M : NODE; SINC_2M : NODE; WR_TM9 : NODE; -- ==================== TEST_SWITCH : NODE; T_SIGNAL : NODE; -- TEST_1 : LCELL; -- KTA[7..0] : LCELL; -- KTD[7..0] : DFF; -- KTT : LCELL; K_DATA[10..0] : NODE; KEY_D[10..0] : DFF; KEY_WRITE : NODE; KD[7..0] : DFF; K_XOR : NODE; NEXT_K : NODE; RED[7..0] : NODE; GREEN[7..0] : NODE; BLUE[7..0] : NODE; BORDER[7..0] : DFFE; KBD_BLK : NODE; DOS : NODE; DOS_ : NODE; MDR[7..0] : NODE; DCPP[7..0] : NODE; MDP[7..0] : DFFE; -- MDP[7..0] : LCELL; PDD[7..0] : LCELL; WR_PORT : NODE; RGMOD[7..0] : DFFE; HDDR[7..0] : DFFE; GLISSER : NODE; BLK_MR : NODE; VIDEO_PG : NODE; AUDIO_CH : NODE; CBL_MODE : NODE; CBL_STEREO : NODE; CBL_MODE16 : NODE; CBL_INT_ENA : NODE; CBL_INT : NODE; CBL_WR : NODE; CBL_XX[7..0] : DFFE; CBL_CNT[7..0] : DFF; CBL_CTX[4..0] : DFFE; CBL_WA[7..0] : DFFE; CBL_WAE : NODE; CBL_IND : NODE; CBL_TAB[4..0] : LCELL; CBL_R[15..0] : DFFE; CBD[7..0] : DFFE; AUDIO_R[15..0] : DFFE; /WAIT_ALL : NODE; BLK_MEM : NODE; SYS_ENA : NODE; SYS_ENA2 : NODE; /SYS : NODE; SYS_PG : NODE; CS_ISA : NODE; ISA_CASH : NODE; ISA_A[3..0] : NODE; PRE_ISA : NODE; PRE_ROM : NODE; PRE_CASH : NODE; WAIT_ORIG : NODE; WAIT_ROM : NODE; WAIT_ROMX : NODE; WT_R[2..0] : DFF; -- BLK_WAIT : NODE; ISA_A20 : NODE; CASH_ON : NODE; BLK_MWR2 : NODE; ROM_RG[7..0]: DFFE; ROM_WRITE_MODE : NODE; AY_CHS[15..0] : DFFE; SOFT_RESET : NODE; SOFT_RES[1..0] : DFF; AY_FULL[10..0] : DFF; ALL_MODE[7..0] : DFFE; DOUBLE_CAS : NODE; XACS : DFF; KEMPS[7..0] : LCELL; KEY/KEMS[7..0] : LCELL; AY/PORTS[7..0] : LCELL; V_WRXX[3..0]: LCELL; V_WRX[3..0] : LCELL; -- V_WRX[3..0] : NODE; KEY_IO : NODE; /IOWR : NODE; /IORD : NODE; RASX_[1..0] : NODE; CASX_[3..0] : NODE; CASXE[1..0] : NODE; CAS_A : NODE; -- ISA_CELL[1..0] : LCELL; T_RDXA : NODE; /WE_OUT : NODE; SINC_HOLD[8..0] : DFF; HOLD[7..0] : DFFE; CS_ROMT : NODE; CS_CASHT : NODE; ISA_PORT[7..0] : DFFE; BEGIN CLK42 = TG42; -- /RESET = TRI(GND,!DFF((KEYS.kb_reset & START_UP & SOFT_RESET),CLK42,,)); -- start_up from SOFT_RESET /RESET = TRI(GND,!DFF((KEYS.kb_reset & SOFT_RESET),CLK42,,)); -- SOFT_RES[].prn = DFF((!DECODE.BLK_R or /WR or !(DECODE.PAGE[7..0] == H"A0")),CLK42,,); SOFT_RES[].clk = !CT4; CASE SOFT_RES[] IS WHEN 0,1 => SOFT_RES[] = GND; WHEN 2 => SOFT_RES[] = 1; WHEN 3 => SOFT_RES[] = 2; END CASE; SOFT_RESET = (SOFT_RES[] == 0); -- when no_Z - RESET! -- ===== Spectrum-Ports =================== /IOWR = DFF((/WR or /IO),CLK42,,!/IO); /IORD = DFF((/RD or /IO),CLK42,,!/IO); BORDER[].clk = /IOWR; BORDER[].ena = DFF((DCPP[] == B"1100X010"),CLK42,,); -- C2/C8 BORDER[].d = D[]; -- ===== keyboard ========================= -- ======================================== -- NEW 30.06.2022 -- KEYS.int_ena = ALL_MODE0; -- int in all keys -- KEYS.ena = !ALL_MODE0; -- ZX-Keyboard KEYS.int_ena = LCELL(ALL_MODE0 & ALL_MODE3); -- new bit3 in ALL_MODE, disables keyboard interruptions w/o accellerator affected KEYS.ena = VCC; -- ZX-Keyboard always enabled -- ======================================== KEYS.clk42 = CLK42; KEYS.clk_k = DFF(CTH5,CLK42,,); KEYS.kbd_cc = KBD_CC or !KBD_BLK; KEYS.kbd_dd = KBD_DD; KD[].clk = CLK42; NEXT_K = TFF(VCC,KEY_WRITE,,); CASE (NEXT_K) IS WHEN 0 => KD[] = H"ED"; WHEN 1 => KD[] = (B"00000",CTF[6..4]); END CASE; K_XOR = !(KD7 xor KD6 xor KD5 xor KD4 xor KD3 xor KD2 xor KD1 xor KD0); K_DATA[] = (VCC,K_XOR,KD[],GND); KEY_D[].clk = KBD_CC; KEY_D[].d = (GND,KEY_D[10..1]); FOR i in 0 to 10 GENERATE KEY_D[i].prn = K_DATA[i] or KEY_WRITE; END GENERATE; KEY_D[].clrn = /RESET; KEY_WRITE = DFF((!DFF(CTF1,CLK42,,) or CTF1),CLK42,,); -- KBD_DX = KEY_D0; -- KBD_BLK = DFF(VCC,CTV7,KEY_WRITE,); KBD_BLK = VCC; KBD_DX = GND; -- ======================================== -- == Data Paths ========================== -- ======================================== MDP[].clk = DECODE./IOMM; CASE (DECODE.TYPE[0],(DECODE.HDD_FLIP & DECODE.HDD_DATA)) IS WHEN B"00" => MDP[] = MD[7..0]; WHEN B"01" => MDP[] = HDDR[7..0]; WHEN B"1X" => MDP[] = MD[15..8]; END CASE; -- HDDR[].clk = DECODE./IOM; HDDR[].clk = LCELL(/WR & (/RD or DECODE./IOMM)); HDDR[].ena = (DECODE.HDD_DATA & !DECODE./IOM); CASE DFF(/WR,DECODE.RAS,,) IS WHEN 0 => HDDR[].d = D[]; WHEN 1 => HDDR[].d = MD[15..8]; END CASE; % CASE (DECODE.MC_END & DECODE.HDD_FLIP) IS WHEN 0 => DMDX[] = (ACC.MDO[7..0]); WHEN 1 => DMDX[] = (HDDR[]); END CASE; % DMDX[] = (ACC.MDO[7..0]); ACC.HDDR[] = HDDR[]; ACC.HDD_FLIP = DECODE.HDD_FLIP; CASE DECODE.TYPE0 IS WHEN 0 => KEY/KEMS[] = (LCELL((KEYS.kbo5 & !CBL_MODE) or (CBL_IND & CBL_MODE)),TAPE_IN,LCELL(CBL_MODE & CTV8),KEYS.kbo[4..0]); AY/PORTS[] = DECODE.DO[]; WHEN 1 => KEY/KEMS[] = KEMPS[]; AY/PORTS[] = AY3.DO[]; END CASE; CASE DECODE.TYPE[2..1] IS WHEN B"11" => PDD[] = MDP[]; WHEN B"10" => PDD[] = KEY/KEMS[]; WHEN B"01" => PDD[] = AY/PORTS[]; WHEN B"00" => PDD[] = VCC; END CASE; CASE /IO IS WHEN 1 => DD[] = ACC.DO[]; WHEN 0 => DD[] = PDD[]; END CASE; -- D_OUT = !(/IO or /RD or LCELL((DCPP[7..4] == 0) or (DCPP[7..4] == 3))) or RD_RAM; D_OUT = !(/IORD or LCELL((DCPP[7..4] == 0) or (DCPP[7..4] == 3))) or RD_RAM; V_WRXX[] = !SVIDEO.V_WEN[]; V_WRX3 = !SVIDEO.V_WEN3; V_WRX2 = !SVIDEO.V_WEN2; V_WRX1 = !SVIDEO.V_WEN1; V_WRX0 = !SVIDEO.V_WEN0; FOR i IN 0 TO 7 GENERATE D[i] = TRI(DD[i],D_OUT); VD3[i] = TRI(DVD3[i],V_WRX3); VD2[i] = TRI(DVD2[i],V_WRX2); VD1[i] = TRI(DVD1[i],V_WRX1); VD0[i] = TRI(DVD0[i],V_WRX0); MD[i] = TRI(DMDX[i],!/WE_OUT or WR_PORT); MD[i+8] = TRI(ACC.MDO[i+8],!/WE_OUT or WR_PORT); -- MD[i+8] = TRI(DMDY[i],!/WE or WR_PORT); END GENERATE; -- ======================================== -- ======================================== -- ======================================== -- ======================================== % IF MODE == "SPECTRUM" GENERATE TEST_SWITCH = TFF((!KEYS.kb_sh & !KEYS.kb_ctrl),KEYS.kb_F12,,); CASE TEST_SWITCH IS WHEN 0 => KEYS./rf = /RF; KEYS./io = /IO; KEYS.a[15..8] = A[15..8]; KEYS./iom = /IO; WHEN 1 => KEYS./rf = DFF((CT4 or CT5),CT2,,); KEYS./io = DFF((CT4 or !CT5),CT2,,); KEYS.a[15..8] = !KTA[]; KEYS./iom = DFF((CT4 or !CT5),CT2,,); END CASE; CASE TEST_SWITCH IS WHEN 0 => RED[] = (SVIDEO.zx_color1 & (VCC,SVIDEO.zx_color3,B"000000")); GREEN[] = (SVIDEO.zx_color2 & (VCC,SVIDEO.zx_color3,B"000000")); BLUE[] = (SVIDEO.zx_color0 & (VCC,SVIDEO.zx_color3,B"000000")); WHEN 1 => RED[] = (CTH[4..0],CT[5..3]) & CTV[4] & BLANK & T_SIGNAL or TEST_1; GREEN[] = (CTH[4..0],CT[5..3]) & CTV[5] & BLANK & T_SIGNAL or TEST_1; BLUE[] = (CTH[4..0],CT[5..3]) & CTV[6] & BLANK & T_SIGNAL or TEST_1; END CASE; DVD0[] = SVIDEO.vdo0[]; DVD3[] = RED[]; DVD2[] = GREEN[]; DVD1[] = BLUE[]; V_WR0 = SVIDEO.v_wr0; V_WR[3..1] = WR_COL; DECODE.TURBO_HAND = VCC; -- ===== TEST CODES ============================================ KTD[].clk = DFF((CT4 or !CT5),CT2,,); KTD[] = KEYS.kbo[]; KTA0 = (CTV[5..3] == 0); KTA1 = (CTV[5..3] == 1); KTA2 = (CTV[5..3] == 2); KTA3 = (CTV[5..3] == 3); KTA4 = (CTV[5..3] == 4); KTA5 = (CTV[5..3] == 5); KTA6 = (CTV[5..3] == 6); KTA7 = (CTV[5..3] == 7); CASE CTH[2..0] IS WHEN 0 => KTT = KTD0; WHEN 1 => KTT = KTD1; WHEN 2 => KTT = KTD2; WHEN 3 => KTT = KTD3; WHEN 4 => KTT = KTD4; WHEN 5 => KTT = KTD5; WHEN 6 => KTT = KTD6; WHEN 7 => KTT = KTD7; END CASE; T_SIGNAL = DFF(((!CTH5 or TAPE_IN) & (CTH5 or MOUSE_D) & KBD_CC),CLK42,,); CASE (CTH[5..3],CTV[8..6]) IS WHEN B"1XXXXX" => TEST_1 = GND; WHEN B"XXX100" => TEST_1 = GND; WHEN B"XXXX11" => TEST_1 = GND; WHEN B"000000" => TEST_1 = TFF(VCC,KEYS.kb_ctrl,,); WHEN B"001000" => TEST_1 = GND; WHEN B"010000" => TEST_1 = GND; WHEN B"011000" => TEST_1 = KTT; WHEN B"000001" => TEST_1 = TFF(VCC,KEYS.kb_alt,,); WHEN B"001001" => TEST_1 = GND; WHEN B"010001" => TEST_1 = GND; WHEN B"011001" => TEST_1 = GND; WHEN B"000010" => TEST_1 = TFF(VCC,KEYS.kb_sh,,); WHEN B"001010" => TEST_1 = GND; WHEN B"010010" => TEST_1 = GND; WHEN B"011010" => TEST_1 = GND; END CASE; ELSE GENERATE % TEST_SWITCH = TFF((!KEYS.kb_sh & !KEYS.kb_ctrl & !KEYS.kb_alt),KEYS.kb_F12,,/RESET); DECODE.TURBO_HAND = TEST_SWITCH; KEY_IO = DFFE((/IO or !/M1),CLK42,,,(CT1 & CT2)); KEYS./rf = DFFE((CT2 or !KEY_IO),CLK42,,,CT0); KEYS./iom = KEY_IO; KEYS./io = KEY_IO; KEYS./m1 = VCC; KEYS.a[15..8] = A[15..8]; DVD0[] = SVIDEO.vdo0[]; DVD1[] = SVIDEO.vdo1[]; DVD2[] = SVIDEO.vdo2[]; DVD3[] = SVIDEO.vdo3[]; V_WR[3..0] = SVIDEO.V_WR[]; % END GENERATE; % -- ===================================================== -- ===================================================== SYS_ENA = (!/SYS or ROM_RG4) or (A[15..4] == B"001111111111") or (A[15..4] == B"00000000000X"); -- SYS_ENA2 = DFFE(SYS_ENA,/MR,,,/RF) & DFF((A[7..0] == B"0X111100"),CLK42,,); SYS_ENA2 = DFF((A[7..0] == B"0X111100"),CLK42,,); ISA_PORT[].clk = /IOWR; ISA_PORT[].d = D[]; ISA_PORT[].ena = DECODE.BLK_R & DFF((DCPP[] == B"1111XXXX"),CLK42,,); IF (UPDATE == 1) GENERATE WAIT_ORIG = LCELL(/MR or CT5 or ALL_MODE2 or LCELL((!(DECODE.V_RAM & (A14 & A15)) & !(A14 & !A15)) or TURBO)); SOFT_RES[].prn = !DFF(DFF((LCELL(DECODE.BLK_R & A14 & A15) & LCELL(DECODE.PAGE[7..4] == H"A")),CLK42,,),(/WR or /MR),/RESET,); -- /SYS=0 - system ROM on /SYS = DFFE(!A6,/IOWR,/RESET,,SYS_ENA2); -- SYS_PG - system ROM0/ROM1 switch SYS_PG = DFFE(D0,/IOWR,/RESET,!ROM_RG4,(SYS_ENA2 & !D1)); -- 0 - write A20 for ISA ISA_A20 = (/IOWR or !DFF((DCPP[] == B"00011011"),CLK42,,)); -- 1B -- ISA_A20 = VCC; -- 1 - CASHE on IN A,(0FBh/07Bh) -- CASH_ON = DFFE(A7,/IORD,/RESET,,DFF((DCPP[] == H"88"),CLK42,,));-- 88 CASH_ON = DFFE(A7,/IORD,/RESET,,DFF((A[7..0] == B"X1111011"),CLK42,,)); -- 0 - CS_ISA PRE_ISA = LCELL(!LCELL(ISA_PORT[] == B"1101XXXX") or !DECODE.BLK_R or !A14 or !A15); PRE_ROM = LCELL(/SYS or A14 or A15 or CASH_ON); PRE_CASH = LCELL(A14 or A15 or !CASH_ON); -- BLK_WAIT = LCELL(LCELL(PRE_CASH or !PRE_ROM) or (/RD & /WR) or /MR); WAIT_ROMX = LCELL(CS_ROM & CS_ISA); WAIT_ROM = (WAIT_ROMX or DFF((WT_R[] == 0),CLK42,!WAIT_ROMX,)); WT_R[].clk = CLK42; CASE (WAIT_ROMX,WT_R[]) IS WHEN 0 => WT_R[] = 0; WHEN B"0001" => WT_R[] = WT_R[] - 1; WHEN B"001X" => WT_R[] = WT_R[] - 1; WHEN B"01XX" => WT_R[] = WT_R[] - 1; WHEN B"1XXX" => WT_R[] = 4; END CASE; CS_ISA = DFF((!/RF or PRE_ISA),!/MR,,LCELL(CS_ISA or !/MR)); CS_ROMT = DFF((!/RF or PRE_ROM or !PRE_CASH),!/MR,,LCELL(CS_ROMT or !/MR)); CS_CASHT = DFF((!/RF or !PRE_ROM or PRE_CASH),!/MR,,LCELL(CS_CASHT or !/MR)); CS_ROM = CS_ROMT; CS_CASH = CS_CASHT & CS_ISA & ISA_A20; -- CS_ROM = LCELL(LCELL(PRE_ROM or !PRE_CASH) or (/RD & /WR) or /MR); -- CS_CASH = LCELL(LCELL(PRE_CASH or !PRE_ROM) or (/RD & /WR) or /MR) & -- CS_ISA & ISA_A20; CASE (PRE_ROM,PRE_CASH) IS WHEN B"00" => ISA_A[] = B"1000"; -- error -> ISA WHEN B"01" => ISA_A[] = ((ROM_RG3 xor !SYS_PG),ROM_RG[2..0]); -- ROM_ADRESS WHEN B"10" => ISA_A[] = (B"01",ROM_RG[1..0]); -- CASHE_ADRESS WHEN B"11" => ISA_A[] = (!PRE_ISA,GND,ISA_PORT[2..1]); -- for ISA_A20 END CASE; RA[] = ISA_A[3..0]; XACS.clk = !(/MR or /WR); XACS.d = (!ROM_RG4 or A14 or A15); XACS.prn = (XACS or (!/MR & ROM_RG4)); -- XACS.clk = CLK42; -- XACS = (WAIT_ROM or /WR or A14 or A15); -- XACS.prn = !/MR & ROM_RG4; BLK_MEM = LCELL(!PRE_ROM or !PRE_CASH or !PRE_ISA); RD_RAM = !(/MR or /RD or BLK_MEM); BLK_MWR2 = DECODE.RAM or BLK_MEM; DECODE.BLK_MEM = BLK_MEM; ROM_RG[].clk = /IOWR; ROM_RG[].d = D[]; ROM_RG[].ena = DFF((DCPP[] == H"8F"),CLK42,,) or (!/SYS & DFF((A[7..0] == B"01011100"),CLK42,,)); -- 5C ROM_RG[].clrn = /RESET; ELSE GENERATE SOFT_RES[].prn = DFF((!DFF(DECODE.BLK_R,CLK42,,) or /WR or !(DECODE.PAGE[7..4] == H"A")),CLK42,,!/MR); WT_R[].clk = GND; WT_R[] = 0; WAIT_ROM = VCC; DECODE.BLK_MEM = GND; BLK_MWR2 = DECODE.BLK_R; XACS.clk = CLK42; CASE ROM_WRITE_MODE IS WHEN 0 => CS_ROM = ROM_RG[4] or !/RF or LCELL(DECODE.CS_ROM or /RD or (DECODE.BLK_R & !LCELL(DECODE.PAGE[7..4] == 14))); XACS = VCC; WHEN 1 => CS_ROM = /MR or !/RF or DFF((/RD & /WR),CLK42,,); -- XACS = /MR or DFF((/WR or DECODE.MC_END),!CLK42,,); XACS = /MR or DFF(/WR or !DFF(/WR,!CT2,,!/WR),!CT2,,!/WR); END CASE; -- CS_CASH = !DECODE.BLK_R or !(DECODE.PAGE[7..4] == 15); -- CS for CASHE & ISA-Slots CS_CASH = (DFF(!(DECODE.PAGE[7..4] == B"11X1"),CLK42,,DECODE.BLK_R) & -- CS for ISA_A20 signal LCELL(DECODE./IOM or /WR or !(DCPP[] == B"00011011")) -- 1B ); -- Switcher for ISA/CASHE adress ISA_CASH = LCELL(DECODE.BLK_R & (DECODE.PAGE[7..4] == B"11X1")) or !/IOWR; CASE /IO IS WHEN 0 => ISA_A[3..2] = B"00"; -- for Write to A20 port ISA_A[1..0] = DECODE.PAGE[1..0]; -- ANY WHEN 1 => -- ISA_A[3..2] = B"10"; -- for ISA Slots ISA_A[3..2] = (!DECODE.PAGE5,DECODE.PAGE5); -- ISA_A[1..0] = DECODE.PAGE[1..0]; -- ISA select ISA_A[1..0] = (DECODE.PAGE2,DECODE.PAGE1); -- ISA select END CASE; RD_RAM = !(DECODE.CS_RAM or /RD or DECODE.BLK_R); CASE ROM_WRITE_MODE IS WHEN 0 => CASE (ISA_CASH,DECODE.RAM) IS WHEN 0 => RA[] = (B"01",A[15..14]); -- for CASHE in RAM WHEN 1 => RA[] = DECODE.RA[]; -- ROM Adresses WHEN 2,3 => RA[] = ISA_A[3..0]; -- CASHE & ISA END CASE; WHEN 1 => RA[] = ROM_RG[3..0]; END CASE; ROM_WRITE_MODE = DFF((ROM_RG[4] & !(A14 or A14)),CLK42,,); ROM_RG[].clk = /IOWR; ROM_RG[].d = D[]; ROM_RG[].ena = DFF((DCPP[] == H"8F"),CLK42,,); ROM_RG[].clrn = /RESET; END GENERATE; -- ===================================================== -- ===================================================== RD_KMPS = DECODE./IOM or /RD or !(DECODE.TYPE[] == 7); -- WR_PORT = !(/IO or DFF(!DECODE.MC_END,CLK42,,) or /WR) or !(DECODE.WR_DWG or /IO or /WR); WR_PORT = (!(/IO or /WR) & LCELL(DFF(DECODE.MC_TYPE,CLK42,,))); -- WR_PORT = DFF((!(/IO or /WR) & DECODE.MC_TYPE),CLK42,,); WR_DWG = DECODE.WR_DWG; -- (NMI_X,KBD_CX) = GND; (KBD_CX) = GND; IF (NMI_ON == "ON") GENERATE NMI_X = (!KEYS.kb_f12 & KEYS.kb_alt); ELSE GENERATE NMI_X = GND; END GENERATE; -- TFF(KEYS.kb_ctrl,KEYS.kb_f12,,); -- INT_X = !DFF(GND,CTV8,,((/IO or /M1) & DFF(!INT_X,CTH3,,))); -- INT_X = !DFF(GND,SVIDEO.INTT,,((/IO or /M1) & DFF(!INT_X,CTH3,,))); -- INT_X = !DFF(GND,(SVIDEO.INTT & KEYS.int),,((/IO or /M1) & DFF(!INT_X,CTH3,,))); INT_X = !DFF(GND,(SVIDEO.INTT & KEYS.int),,((/IO or /M1) & DFF(DFF(!INT_X,CTH2,,),CTH2,,))) or !CBL_INT; TAPE_OUT = LCELL(BORDER3); -- *************************************** -- RDXA = LCELL(DECODE.RD_KP11); -- T_RDXA = DFF(GND,DECODE.RD_KP11,,DFF((T_RDXA),CLK42,,)); -- WR_TM9 = !DFF(VCC,!CLK42,DECODE.WR_TM9,); -- WR_TM9 = LCELL(DFF(DECODE.RD_KP11,CLK42,,)); -- RDXA = LCELL(CT2 or DFFE(!CT2,!CLK42,,,CT1)); RDXA = DFF(!((CT[2..0] == B"11X") or (CT[2..0] == 0)),CLK42,,); -- T_RDXA = CT2; T_RDXA = LCELL(RDXA); -- WR_TM9 = DFF(CT2,!CLK42,,); WR_TM9 = LCELL(CT2); -- SXA = TFF(VCC,T_RDXA,,); -- SXA = DFF((CT3 xor (CT2 & CT1)),CLK42,,); SXA = DFF((CT3 xor CT2),CLK42,,); -- WR_AWG = LCELL(LCELL(DECODE.WR_AWG)); -- WR_AWG = LCELL(DECODE.WR_AWG); WR_AWG = DECODE.WR_AWG; -- WR_AWG = DFF(DECODE.WR_AWG,CLK42,,); -- SXA = DFF(DECODE.KP11_MIX,CLK42,,); XA0 = TRI(KBD_CX,WR_TM9); XA1 = TRI(KBD_DX,WR_TM9); XA2 = TRI(TAPE_OUT,WR_TM9); XA3 = TRI(GND,GND); KBD_DD = DFFE(XA1,T_RDXA,,,!SXA); KBD_CC = DFFE(XA0,T_RDXA,,,!SXA); TAPE_IN = DFFE(XA2,T_RDXA,,,!SXA); MOUSE_D = DFFE(XA3,T_RDXA,,,!SXA); FDD_CH = DFFE(XA1,T_RDXA,,,SXA); FDD_W = DFFE(XA0,T_RDXA,,,SXA); SINC_1 = DFFE(XA2,T_RDXA,DECODE./RES,,SXA); SINC_2 = DFFE(XA3,T_RDXA,DECODE./RES,,SXA); SINC_HOLD[3..0].clk = CT4; SINC_HOLD[8..4].clk = CTH5; SINC_1M = DFF(!(SINC_HOLD[3..0] == 15),CLK42,,); CASE !SINC_1 IS WHEN 0 => SINC_HOLD[3..0] = HOLD[3..0]; WHEN 1 => SINC_HOLD[3..0] = (SINC_HOLD[3..0] + 1) or !SINC_1M; END CASE; SINC_2M = DFF(!(SINC_HOLD[8..4] == B"1111X"),CLK42,,); -- CASE DFF((SINC_2 & DFF(SINC_2,CTV0,,)),CLK42,,) IS CASE SINC_2 IS WHEN 1 => SINC_HOLD[8..4] = (HOLD[7..4],GND); WHEN 0 => SINC_HOLD[8..4] = (SINC_HOLD[8..4] + 1) or !SINC_2M; END CASE; COPY_SINC_H = DFF((!SINC_1M & DFF(SINC_1M,CLK42,,)),CLK42,,); COPY_SINC_V = DFF((!SINC_2M & DFF(SINC_2M,CLK42,,)),CLK42,,); -- COPY_SINC_H = DFF(DFF(!SINC_1 & DFF(SINC_1,!CLK42,,),!CLK42,,),CLK42,,); -- COPY_SINC_V = DFF(DFF(!SINC_2 & DFF(SINC_2,!CLK42,,),!CLK42,,),CLK42,,); -- START_UP = DFFE(DFFE(DFFE(VCC,CLK42,,,COPY_SINC_H),CLK42,,,COPY_SINC_V),CLK42,,,COPY_SINC_V); START_UP = DFFE(DFFE(DFFE(VCC,CLK42,,,COPY_SINC_H),CLK42,,,COPY_SINC_H),CLK42,,,COPY_SINC_H); HOLD[].clk = /IOWR; HOLD[].ena = DFF((DCPP[] == B"11001011"),CLK42,,); -- CB HOLD[].d = D[]; HOLD[2..0].prn = DECODE./RES; HOLD[3].clrn = DECODE./RES; HOLD[6..4].prn = DECODE./RES; HOLD[7].clrn = DECODE./RES; -- ===================================================== -- ===== DCP =========================================== -- ===================================================== DOS_ = (!((DECODE.PN4Q & A13 & A12) & (A[11..8] == B"1101")) & DOS) or (A14 or A15); DOS = DFF(DOS_,!(/M1 or /MR),,/RESET); DECODE.DOS = DOS; DECODE.REFRESH = CT4; DCPP[] = DECODE.DCPP[]; DECODE.CLK42 = CLK42; DECODE./RESET = /RESET; DECODE.ACC_ON = ACC.ACC_ON; DECODE.CT[2..0] = CT[2..0]; RASX_[1..0] = (LCELL(DECODE.RAS),LCELL(DECODE.RAS)); RAS_[] = RASX_[]; MCA[] = DECODE.MCA[1..0]; DOUBLE_CAS = ACC.DOUBLE_CAS; CAS_A = LCELL(DECODE.CAS); -- CAS_A = (DECODE.CAS); CASXE0 = LCELL((MCA0 == 0) or ((MCA0 == 1) & DOUBLE_CAS)); CASXE1 = LCELL((MCA0 == 1) or ((MCA0 == 0) & DOUBLE_CAS)); CASX_0 = LCELL(CAS_A or !((!MCA1 & CASXE0) or DECODE.MC_TYPE)); CASX_1 = LCELL(CAS_A or !((!MCA1 & CASXE1) or DECODE.MC_TYPE)); CASX_2 = LCELL(CAS_A or !(( MCA1 & CASXE0) or DECODE.MC_TYPE)); CASX_3 = LCELL(CAS_A or !(( MCA1 & CASXE1) or DECODE.MC_TYPE)); CAS_[] = CASX_[]; -- /WE = DFFE((/WE_OUT or DECODE.RAS),CLK42,,/RESET,); /WE = DFFE((/WE_OUT or DECODE.RAS),CLK42,,/RESET,); -- /WE = LCELL(DFFE((/WE_OUT or DECODE.RAS),CLK42,,/RESET,)); -- /WE = LCELL(/WE_OUT or CAS_A); /WE_OUT = LCELL(DECODE.MC_WRITE or BLK_MR or BLK_MWR2); DECODE.DOUBLE_CAS = DOUBLE_CAS; -- DECODE.A[15..0] = A[]; DECODE.A[15..0] = ACC.AO[]; DECODE.DI[7..0] = D[]; MA[11..0] = DECODE.MA[11..0]; MA[14..12] = (!TURBO,INT_X,NMI_X); CLKZ1 = DECODE.CLK_Z80; TURBO = DECODE.TURBO; DECODE./IO = /IO; DECODE./RD = /RD; DECODE./WR = /WR; DECODE./MR = /MR; DECODE./RF = /RF; DECODE./M1 = /M1; /WAIT_ALL = (DECODE./WAIT & WAIT_ROM & WAIT_ORIG); -- /WAIT = TRI(DECODE./WAIT,LCELL(!(DECODE./WAIT & DFF(DECODE./WAIT,CLK42,,)))); /WAIT = TRI(/WAIT_ALL,LCELL(!/WAIT_ALL)); DECODE.TEST_R = TFF(KEYS.kb_ctrl,KEYS.kb_f12,,); -- DECODE.MD[7..0] = ACC.MD[]; DECODE.MD[7..0] = ACC.DO[]; -- ===================================================== -- == Accelerator ====================================== -- ===================================================== ACC.ACC_ENA = ALL_MODE0; ACC.CLK42 = CLK42; ACC./RESET = /RESET; ACC.CT[2..0]= CT[2..0]; ACC.CLK_Z80 = DECODE.CLK_Z80; ACC.RAS = DECODE.RAS; ACC.CAS = DECODE.CAS; DECODE.CONTINUE = ACC.CONTINUE; -- DECODE.CONTINUE = VCC; ACC.MC_END = DECODE.MC_END; ACC.MC_BEGIN= DECODE.MC_BEGIN; ACC.MC_TYPE = DECODE.MC_TYPE; ACC.MC_WRITE= DECODE.MC_WRITE; -- ACC.MCA[] = DECODE.MCA[]; ACC.AI[15..0] = A[]; ACC.DI[7..0] = D[]; ACC./IO = /IO; ACC./RD = /RD; ACC./WR = /WR; ACC./MR = /MR; ACC./RF = /RF; ACC./M1 = /M1; ACC./IOM = DECODE./IOM; ACC.DCP[7..0] = DCPP[]; ACC.MDI[15..0] = MD[]; -- ACC.MDO[15..0]; -- ===================================================== -- ===== Graf-Mode ===================================== -- ===================================================== RGMOD[].clk = /IOWR; RGMOD[].ena = DFF((DCPP[] == B"1100X101"),CLK42,,); -- (DCPP[] == B"1100X101"); RGMOD[].d = D[]; RGMOD[].clrn= /RESET; DECODE.G_LINE[] = (GND,GND,ACC.G_LINE[7..0]); -- ===================================================== -- ===== VIDEO ========================================= -- ===================================================== VIDEO_PG = LCELL(DECODE.PAGE[7..4] == B"0101"); BLK_MR = LCELL((VIDEO_PG & (DECODE.PAGE2 or (DECODE.PAGE3 & ACC.GLISSER)))); GLISSER = LCELL(ACC.GLISSER & DECODE.PAGE[3] & VIDEO_PG); SVIDEO.clk42 = CLK42; CT[5..0] = SVIDEO.ct[5..0]; CTH[5..0] = SVIDEO.cth[5..0]; CTV[8..0] = SVIDEO.ctv[8..0]; CTF[6..0] = SVIDEO.ctf[6..0]; BLANK = SVIDEO.blank; SVIDEO.start_up = VCC; SVIDEO.copy_sinc_h = COPY_SINC_H; SVIDEO.copy_sinc_v = COPY_SINC_V; -- SVIDEO.wr = (DECODE.MC_WRITE or DECODE.CAS or GLISSER); -- SVIDEO.wr = DFF((DECODE.MC_WRITE or GLISSER or DECODE.RAS),CLK42,,/RESET); SVIDEO.wr = DFF((DECODE.MC_WRITE or GLISSER or DECODE.CAS),!CLK42,,/RESET); -- SVIDEO.vai[] = (DECODE.GA[],A[9..0]); SVIDEO.vai[] = (DECODE.GA[],ACC.AO[9..0]); VA[] = SVIDEO.vao[]; SVIDEO.D[] = D[]; SVIDEO.MDI[] = ACC.MDO[]; SVIDEO.DOUBLE_CAS = DOUBLE_CAS; SVIDEO.VDM0[7..0] = VD0[]; SVIDEO.VDM1[7..0] = VD1[]; SVIDEO.VDM2[7..0] = VD2[]; SVIDEO.VDM3[7..0] = VD3[]; V_CS[1..0] = SVIDEO.v_cs[]; WR_COL = SVIDEO.WR_PIX; -- ZX_COLOR[3..0] SVIDEO.ZX_PORT[5..0] = (ACC.G_LINE[5..0]); SVIDEO.ZX_PORT[7..6] = (DECODE.SP_SA,LCELL(DECODE.SP_SCR & !(A13 & !ACC.G_LINE7) & !ACC.G_LINE6)); SVIDEO.DIR_PORT[0] = DECODE.SCR128; SVIDEO.DIR_PORT[3] = RGMOD0; IF (SCREEN_OFF == "USE") GENERATE SVIDEO.DIR_PORT[4] = RGMOD1; -- 1 screen off, 0 - screen on ELSE GENERATE SVIDEO.DIR_PORT[4] = GND; -- 1 screen off, 0 - screen on END GENERATE; SVIDEO.DIR_PORT[2..1] = GND; SVIDEO.DIR_PORT[7..5] = BORDER[2..0]; -- SVIDEO.DIR_PORT[7..5] = MS.OUT_X[7..5]; SVIDEO.MOUSE_X[] = MS.OUT_X[]; SVIDEO.MOUSE_Y[] = MS.OUT_Y[]; % bit0 - Spectrum SCREEN Switch bit1 - Spectrum Adress MODE bit2 - Write to Spectrum Screen OFF bit7..5 - Border % -- ===================================================== ALL_MODE[7..0].clk = /IOWR; ALL_MODE[7..0].ena = DFF((DCPP[] == B"11000011"),CLK42,,); -- C3 ALL_MODE[].d = D[]; ALL_MODE[].prn = /RESET; -- ===================================================== -- === AUDIO OUT ======================================= -- ===================================================== DAC_DATA = DFFE(DFF(AUDIO_R15,CT2,,),!CT2,,,); -- DAC_DATA = DFF(AUDIO_R15,CLK42,,); -- DAC_DATA = AUDIO_R15; DAC_WS = DFF(CTH1,CLK42,,); DAC_BCK = DFF(CT2,CLK42,,); AUDIO_R[15..0].clk = CLK42; AUDIO_R[15..0].ena = !CT2 & DFF(CT2,CLK42,,); AUDIO_CH = DFF(((CTH0,CT[5..3]) == 15),CT2,,); IF AUDIO_CH THEN AUDIO_R[15..0].d = AY_CHS[15..0]; ELSE AUDIO_R[15..0].d = (AUDIO_R[14..0],GND); END IF; -- ====== COVOX ========== CBL_MODE = CBL_XX7; CBL_STEREO = CBL_XX6; CBL_MODE16 = CBL_XX5; CBL_INT_ENA = CBL_XX4; CBL_INT = DFF(GND,!CBL_CNT6,,(CBL_INT_ENA & (/IO or /M1))); CBL_XX[].clk = /IOWR; CBL_XX[].ena = DFF((DCPP[] == B"10001001"),CLK42,,); -- 89 CBL_XX[] = D[]; CBL_CTX[].clk = !CTH1; CBL_CNT[].clk = !CTH1; CASE CBL_XX[3..0] IS WHEN 0 => CBL_TAB[] = 13; -- 16khz -- mono/stereo WHEN 1 => CBL_TAB[] = 9; -- 22khz -- mono/stereo WHEN 2 => CBL_TAB[] = 0; -- reserved WHEN 3 => CBL_TAB[] = 0; -- reserved WHEN 4 => CBL_TAB[] = 0; -- reserved WHEN 5 => CBL_TAB[] = 0; -- reserved WHEN 6 => CBL_TAB[] = 0; -- reserved WHEN 7 => CBL_TAB[] = 0; -- reserved WHEN 8 => CBL_TAB[] = 27; -- 7.8125 KHz -- mono/stereo 8/16 bit WHEN 9 => CBL_TAB[] = 19; -- 10.9375 KHz -- mono/stereo 8/16 bit WHEN 10=> CBL_TAB[] = 13; -- 15.625 KHz -- mono/stereo 8/16 bit WHEN 11=> CBL_TAB[] = 9; -- 21.875 KHz -- mono/stereo 8/16 bit WHEN 12=> CBL_TAB[] = 6; -- 31.25 KHz -- mono/stereo 8/16 bit WHEN 13=> CBL_TAB[] = 4; -- 43.75 KHz -- mono/stereo 8/16 bit WHEN 14=> CBL_TAB[] = 3; -- 54.6875 KHz -- mono/stereo 8/16 bit WHEN 15=> CBL_TAB[] = 1; -- 109.375 KHz -- mono/stereo 8/16 bit -- WHEN 15=> CBL_TAB[] = 0; -- (218.75)KHz -- stereo 110 only END CASE; IF (CBL_CTX[] == 0) THEN CBL_CTX[].d = CBL_TAB[]; ELSE CBL_CTX[].d = CBL_CTX[] - 1; END IF; CASE (CBL_STEREO,LCELL(CBL_CTX[] == 0)) IS WHEN 0,2 => CBL_CNT[].d = CBL_CNT[]; WHEN 1 => CBL_CNT[].d = CBL_CNT[]+1; WHEN 3 => CBL_CNT[].d = CBL_CNT[]+2; END CASE; CBL_CNT[].clrn = CBL_MODE; CBL_IND = CBL_CNT7 xor CBL_WA7; -- CBL_WR = DFF((DCPP[] == B"10001000"),CLK42,,) & !/IOWR; -- 88 CBL_WR = (DFF((DCPP[] == B"10001000"),CLK42,,) & !/IOWR) or (DFF((DECODE.PAGE[7..0] == B"11111101"),CLK42,(CBL_INT_ENA & ACC.ACC_DIR1),) & !DFF((DECODE.MC_WRITE or DECODE.CAS),CLK42,,/RESET)); CBL_WAE = CBL_MODE16 & DFF(!CBL_WAE,!CBL_WR,,CBL_INT); CBL_WA[].clk = !CBL_WR; CBL_WA[].ena = !CBL_WAE; CBL_WA[7].clrn = CBL_MODE & CBL_INT_ENA & (CBL_INT or !CBL_CNT7); CBL_WA[7].prn = (CBL_INT or CBL_CNT7); CBL_WA[6..0].clrn = CBL_MODE & CBL_INT_ENA & CBL_INT; CBL_WA[].d = CBL_WA[] + 1; CBD[].clk = !CBL_WR; CBD[].ena = CBL_WAE; -- CBD[].d = D[]; CBD[].d = ACC.MDO[7..0]; CBD[].clrn = CBL_MODE16; CBL.wren = (CBL_WR & !CBL_WAE); -- CBL.data[] = ((D7 xor CBL_MODE16),D[6..0],CBD[]); CBL.data[] = ((ACC.MDO15 xor CBL_MODE16),ACC.MDO[14..8],CBD[]); CBL.wraddress[] = ((!A[15..8]) & !CBL_INT_ENA) xor CBL_WA[]; CBL.wrclock = CLK42; CBL.wrclken = VCC; CBL.rden = VCC; CBL.rdaddress[] = (CBL_CNT[7..1],LCELL((CBL_CNT0 & !CBL_STEREO) or (AUDIO_CH & CBL_STEREO))); CBL.rdclock = CLK42; CBL.rdclken = VCC; CBL_R[].ena = DFF((CBL_MODE or (CBL_WR)),CLK42,,); CBL_R[].CLK = CLK42; CBL_R[15].prn = /RESET; CBL_R[14..0].clrn = /RESET; CASE CBL_MODE IS WHEN 0 => CBL_R[] = (D[7..0],B"00000000"); WHEN 1 => CBL_R[] = CBL.q[]; END CASE; -- ====== AY-3-8910 ======== AY3.CLK42 = CLK42; AY3./RESET = /RESET; AY3.AY_T[8..0] = (CTH[2..0],CT[5..0]); AY3.AY_D_WR = DFF((DECODE./IOM or /WR) or !DFF((DCPP[] == H"91"),CLK42,,),CLK42,,); AY3.AY_A_WR = DFF((DECODE./IOM or /WR) or !DFF((DCPP[] == H"90"),CLK42,,),CLK42,,); AY3.D[7..0] = D[]; AY3.BEEPER = BORDER4; -- AY3.DO[7..0] : OUTPUT; -- AY3.AY_CH_A[3..0] : OUTPUT; -- AY3.AY_CH_B[3..0] : OUTPUT; -- AY3.AY_CH_C[3..0] : OUTPUT; AY_FULL[].clk = CLK42; -- AY_CHS[].clk = !CTH0; AY_CHS[].clk = !DFF((CTH1 & (CTH0 or !CT5)),CLK42,,); AY_CHS[].ena = VCC; -- AY_FULL[] = (GND,AY_CH_L[]) + (GND,AY_CH_R[]); CASE DFF(CTH0,CLK42,,) IS WHEN 0 => AY_FULL[] = (AY3.AY_CH_L[],GND); WHEN 1 => AY_FULL[] = (AY3.AY_CH_R[],GND); END CASE; -- AY_CHS[].d = (((GND,AY_FULL[]) + (VCC,CBL.q[15..5])),B"0000"); -- AY_CHS[].d = (((GND,AY_FULL[]) + (VCC,CBL.q[15..8],B"000")),B"0000"); AY_CHS[].d = (((GND,AY_FULL[]) + (VCC,CBL_R[15..5])),CBL_R[4..1]); -- ===== MOUSE ========================= MS.clk = DFF(CTH5,CLK42,,); MS.mouse_d = MOUSE_D; CASE (A10,A8) IS WHEN 0,2 => KEMPS[] = (B"111111",!MS.OUT_K0,!MS.OUT_K1); WHEN 1 => KEMPS[] = (MS.OUT_X[7..0]); WHEN 3 => KEMPS[] = !(MS.OUT_Y[7..0]); END CASE; END;