From 3975fdfe4275347dab666e43dbfdaebe80c58ff8 Mon Sep 17 00:00:00 2001 From: Mike Stirling Date: Tue, 12 Jul 2011 20:52:34 +0100 Subject: Initial commit. Some modules imported from experimental 6502 platform. Project added for Quartus 9.1 --- CII_Starter_pin_assignments.csv | 449 +++++++++++++++++ README | 2 + T65/T65.vhd | 551 ++++++++++++++++++++ T65/T65_ALU.vhd | 260 ++++++++++ T65/T65_MCode.vhd | 1052 +++++++++++++++++++++++++++++++++++++++ T65/T65_Pack.vhd | 117 +++++ bbc_micro.qpf | 30 ++ bbc_micro_de1.qsf | 503 +++++++++++++++++++ mc6845.vhd | 419 ++++++++++++++++ vidproc.vhd | 192 +++++++ 10 files changed, 3575 insertions(+) create mode 100644 CII_Starter_pin_assignments.csv create mode 100644 README create mode 100644 T65/T65.vhd create mode 100644 T65/T65_ALU.vhd create mode 100644 T65/T65_MCode.vhd create mode 100644 T65/T65_Pack.vhd create mode 100644 bbc_micro.qpf create mode 100644 bbc_micro_de1.qsf create mode 100644 mc6845.vhd create mode 100644 vidproc.vhd diff --git a/CII_Starter_pin_assignments.csv b/CII_Starter_pin_assignments.csv new file mode 100644 index 0000000..07e4fe5 --- /dev/null +++ b/CII_Starter_pin_assignments.csv @@ -0,0 +1,449 @@ + +# Note: The column header names should not be changed if you wish to import this .csv file into the Quartus II software. + +From,To,Assignment Name,Value,Enabled +,GPIO_0[0],Location,PIN_A13,Yes +,GPIO_0[1],Location,PIN_B13,Yes +,GPIO_0[2],Location,PIN_A14,Yes +,GPIO_0[3],Location,PIN_B14,Yes +,GPIO_0[4],Location,PIN_A15,Yes +,GPIO_0[5],Location,PIN_B15,Yes +,GPIO_0[6],Location,PIN_A16,Yes +,GPIO_0[7],Location,PIN_B16,Yes +,GPIO_0[8],Location,PIN_A17,Yes +,GPIO_0[9],Location,PIN_B17,Yes +,GPIO_0[10],Location,PIN_A18,Yes +,GPIO_0[11],Location,PIN_B18,Yes +,GPIO_0[12],Location,PIN_A19,Yes +,GPIO_0[13],Location,PIN_B19,Yes +,GPIO_0[14],Location,PIN_A20,Yes +,GPIO_0[15],Location,PIN_B20,Yes +,GPIO_0[16],Location,PIN_C21,Yes +,GPIO_0[17],Location,PIN_C22,Yes +,GPIO_0[18],Location,PIN_D21,Yes +,GPIO_0[19],Location,PIN_D22,Yes +,GPIO_0[20],Location,PIN_E21,Yes +,GPIO_0[21],Location,PIN_E22,Yes +,GPIO_0[22],Location,PIN_F21,Yes +,GPIO_0[23],Location,PIN_F22,Yes +,GPIO_0[24],Location,PIN_G21,Yes +,GPIO_0[25],Location,PIN_G22,Yes +,GPIO_0[26],Location,PIN_J21,Yes +,GPIO_0[27],Location,PIN_J22,Yes +,GPIO_0[28],Location,PIN_K21,Yes +,GPIO_0[29],Location,PIN_K22,Yes +,GPIO_0[30],Location,PIN_J19,Yes +,GPIO_0[31],Location,PIN_J20,Yes +,GPIO_0[32],Location,PIN_J18,Yes +,GPIO_0[33],Location,PIN_K20,Yes +,GPIO_0[34],Location,PIN_L19,Yes +,GPIO_0[35],Location,PIN_L18,Yes +,GPIO_1[0],Location,PIN_H12,Yes +,GPIO_1[1],Location,PIN_H13,Yes +,GPIO_1[2],Location,PIN_H14,Yes +,GPIO_1[3],Location,PIN_G15,Yes +,GPIO_1[4],Location,PIN_E14,Yes +,GPIO_1[5],Location,PIN_E15,Yes +,GPIO_1[6],Location,PIN_F15,Yes +,GPIO_1[7],Location,PIN_G16,Yes +,GPIO_1[8],Location,PIN_F12,Yes +,GPIO_1[9],Location,PIN_F13,Yes +,GPIO_1[10],Location,PIN_C14,Yes +,GPIO_1[11],Location,PIN_D14,Yes +,GPIO_1[12],Location,PIN_D15,Yes +,GPIO_1[13],Location,PIN_D16,Yes +,GPIO_1[14],Location,PIN_C17,Yes +,GPIO_1[15],Location,PIN_C18,Yes +,GPIO_1[16],Location,PIN_C19,Yes +,GPIO_1[17],Location,PIN_C20,Yes +,GPIO_1[18],Location,PIN_D19,Yes +,GPIO_1[19],Location,PIN_D20,Yes +,GPIO_1[20],Location,PIN_E20,Yes +,GPIO_1[21],Location,PIN_F20,Yes +,GPIO_1[22],Location,PIN_E19,Yes +,GPIO_1[23],Location,PIN_E18,Yes +,GPIO_1[24],Location,PIN_G20,Yes +,GPIO_1[25],Location,PIN_G18,Yes +,GPIO_1[26],Location,PIN_G17,Yes +,GPIO_1[27],Location,PIN_H17,Yes +,GPIO_1[28],Location,PIN_J15,Yes +,GPIO_1[29],Location,PIN_H18,Yes +,GPIO_1[30],Location,PIN_N22,Yes +,GPIO_1[31],Location,PIN_N21,Yes +,GPIO_1[32],Location,PIN_P15,Yes +,GPIO_1[33],Location,PIN_N15,Yes +,GPIO_1[34],Location,PIN_P17,Yes +,GPIO_1[35],Location,PIN_P18,Yes +,GPIO_0[0],I/O Standard,LVTTL,Yes +,GPIO_0[1],I/O Standard,LVTTL,Yes +,GPIO_0[2],I/O Standard,LVTTL,Yes +,GPIO_0[3],I/O Standard,LVTTL,Yes +,GPIO_0[4],I/O Standard,LVTTL,Yes +,GPIO_0[5],I/O Standard,LVTTL,Yes +,GPIO_0[6],I/O Standard,LVTTL,Yes +,GPIO_0[7],I/O Standard,LVTTL,Yes +,GPIO_0[8],I/O Standard,LVTTL,Yes +,GPIO_0[9],I/O Standard,LVTTL,Yes +,GPIO_0[10],I/O Standard,LVTTL,Yes +,GPIO_0[11],I/O Standard,LVTTL,Yes +,GPIO_0[12],I/O Standard,LVTTL,Yes +,GPIO_0[13],I/O Standard,LVTTL,Yes +,GPIO_0[14],I/O Standard,LVTTL,Yes +,GPIO_0[15],I/O Standard,LVTTL,Yes +,GPIO_0[16],I/O Standard,LVTTL,Yes +,GPIO_0[17],I/O Standard,LVTTL,Yes +,GPIO_0[18],I/O Standard,LVTTL,Yes +,GPIO_0[19],I/O Standard,LVTTL,Yes +,GPIO_0[20],I/O Standard,LVTTL,Yes +,GPIO_0[21],I/O Standard,LVTTL,Yes +,GPIO_0[22],I/O Standard,LVTTL,Yes +,GPIO_0[23],I/O Standard,LVTTL,Yes +,GPIO_0[24],I/O Standard,LVTTL,Yes +,GPIO_0[25],I/O Standard,LVTTL,Yes +,GPIO_0[26],I/O Standard,LVTTL,Yes +,GPIO_0[27],I/O Standard,LVTTL,Yes +,GPIO_0[28],I/O Standard,LVTTL,Yes +,GPIO_0[29],I/O Standard,LVTTL,Yes +,GPIO_0[30],I/O Standard,LVTTL,Yes +,GPIO_0[31],I/O Standard,LVTTL,Yes +,GPIO_0[32],I/O Standard,LVTTL,Yes +,GPIO_0[33],I/O Standard,LVTTL,Yes +,GPIO_0[34],I/O Standard,LVTTL,Yes +,GPIO_0[35],I/O Standard,LVTTL,Yes +,GPIO_1[0],I/O Standard,LVTTL,Yes +,GPIO_1[1],I/O Standard,LVTTL,Yes +,GPIO_1[2],I/O Standard,LVTTL,Yes +,GPIO_1[3],I/O Standard,LVTTL,Yes +,GPIO_1[4],I/O Standard,LVTTL,Yes +,GPIO_1[5],I/O Standard,LVTTL,Yes +,GPIO_1[6],I/O Standard,LVTTL,Yes +,GPIO_1[7],I/O Standard,LVTTL,Yes +,GPIO_1[8],I/O Standard,LVTTL,Yes +,GPIO_1[9],I/O Standard,LVTTL,Yes +,GPIO_1[10],I/O Standard,LVTTL,Yes +,GPIO_1[11],I/O Standard,LVTTL,Yes +,GPIO_1[12],I/O Standard,LVTTL,Yes +,GPIO_1[13],I/O Standard,LVTTL,Yes +,GPIO_1[14],I/O Standard,LVTTL,Yes +,GPIO_1[15],I/O Standard,LVTTL,Yes +,GPIO_1[16],I/O Standard,LVTTL,Yes +,GPIO_1[17],I/O Standard,LVTTL,Yes +,GPIO_1[18],I/O Standard,LVTTL,Yes +,GPIO_1[19],I/O Standard,LVTTL,Yes +,GPIO_1[20],I/O Standard,LVTTL,Yes +,GPIO_1[21],I/O Standard,LVTTL,Yes +,GPIO_1[22],I/O Standard,LVTTL,Yes +,GPIO_1[23],I/O Standard,LVTTL,Yes +,GPIO_1[24],I/O Standard,LVTTL,Yes +,GPIO_1[25],I/O Standard,LVTTL,Yes +,GPIO_1[26],I/O Standard,LVTTL,Yes +,GPIO_1[27],I/O Standard,LVTTL,Yes +,GPIO_1[28],I/O Standard,LVTTL,Yes +,GPIO_1[29],I/O Standard,LVTTL,Yes +,GPIO_1[30],I/O Standard,LVTTL,Yes +,GPIO_1[31],I/O Standard,LVTTL,Yes +,GPIO_1[32],I/O Standard,LVTTL,Yes +,GPIO_1[33],I/O Standard,LVTTL,Yes +,GPIO_1[34],I/O Standard,LVTTL,Yes +,GPIO_1[35],I/O Standard,LVTTL,Yes +,SW[0],Location,PIN_L22,Yes +,SW[1],Location,PIN_L21,Yes +,SW[2],Location,PIN_M22,Yes +,SW[3],Location,PIN_V12,Yes +,SW[4],Location,PIN_W12,Yes +,SW[5],Location,PIN_U12,Yes +,SW[6],Location,PIN_U11,Yes +,SW[7],Location,PIN_M2,Yes +,SW[8],Location,PIN_M1,Yes +,SW[9],Location,PIN_L2,Yes +,SW[0],I/O Standard,LVTTL,Yes +,SW[1],I/O Standard,LVTTL,Yes +,SW[2],I/O Standard,LVTTL,Yes +,SW[3],I/O Standard,LVTTL,Yes +,SW[4],I/O Standard,LVTTL,Yes +,SW[5],I/O Standard,LVTTL,Yes +,SW[6],I/O Standard,LVTTL,Yes +,SW[7],I/O Standard,LVTTL,Yes +,SW[8],I/O Standard,LVTTL,Yes +,SW[9],I/O Standard,LVTTL,Yes +,HEX0[0],Location,PIN_J2,Yes +,HEX0[1],Location,PIN_J1,Yes +,HEX0[2],Location,PIN_H2,Yes +,HEX0[3],Location,PIN_H1,Yes +,HEX0[4],Location,PIN_F2,Yes +,HEX0[5],Location,PIN_F1,Yes +,HEX0[6],Location,PIN_E2,Yes +,HEX1[0],Location,PIN_E1,Yes +,HEX1[1],Location,PIN_H6,Yes +,HEX1[2],Location,PIN_H5,Yes +,HEX1[3],Location,PIN_H4,Yes +,HEX1[4],Location,PIN_G3,Yes +,HEX1[5],Location,PIN_D2,Yes +,HEX1[6],Location,PIN_D1,Yes +,HEX2[0],Location,PIN_G5,Yes +,HEX2[1],Location,PIN_G6,Yes +,HEX2[2],Location,PIN_C2,Yes +,HEX2[3],Location,PIN_C1,Yes +,HEX2[4],Location,PIN_E3,Yes +,HEX2[5],Location,PIN_E4,Yes +,HEX2[6],Location,PIN_D3,Yes +,HEX3[0],Location,PIN_F4,Yes +,HEX3[1],Location,PIN_D5,Yes +,HEX3[2],Location,PIN_D6,Yes +,HEX3[3],Location,PIN_J4,Yes +,HEX3[4],Location,PIN_L8,Yes +,HEX3[5],Location,PIN_F3,Yes +,HEX3[6],Location,PIN_D4,Yes +,HEX0[0],I/O Standard,LVTTL,Yes +,HEX0[1],I/O Standard,LVTTL,Yes +,HEX0[2],I/O Standard,LVTTL,Yes +,HEX0[3],I/O Standard,LVTTL,Yes +,HEX0[4],I/O Standard,LVTTL,Yes +,HEX0[5],I/O Standard,LVTTL,Yes +,HEX0[6],I/O Standard,LVTTL,Yes +,HEX1[0],I/O Standard,LVTTL,Yes +,HEX1[1],I/O Standard,LVTTL,Yes +,HEX1[2],I/O Standard,LVTTL,Yes +,HEX1[3],I/O Standard,LVTTL,Yes +,HEX1[4],I/O Standard,LVTTL,Yes +,HEX1[5],I/O Standard,LVTTL,Yes +,HEX1[6],I/O Standard,LVTTL,Yes +,HEX2[0],I/O Standard,LVTTL,Yes +,HEX2[1],I/O Standard,LVTTL,Yes +,HEX2[2],I/O Standard,LVTTL,Yes +,HEX2[3],I/O Standard,LVTTL,Yes +,HEX2[4],I/O Standard,LVTTL,Yes +,HEX2[5],I/O Standard,LVTTL,Yes +,HEX2[6],I/O Standard,LVTTL,Yes +,HEX3[0],I/O Standard,LVTTL,Yes +,HEX3[1],I/O Standard,LVTTL,Yes +,HEX3[2],I/O Standard,LVTTL,Yes +,HEX3[3],I/O Standard,LVTTL,Yes +,HEX3[4],I/O Standard,LVTTL,Yes +,HEX3[5],I/O Standard,LVTTL,Yes +,HEX3[6],I/O Standard,LVTTL,Yes +,KEY[0],Location,PIN_R22,Yes +,KEY[1],Location,PIN_R21,Yes +,KEY[2],Location,PIN_T22,Yes +,KEY[3],Location,PIN_T21,Yes +,LEDR[0],Location,PIN_R20,Yes +,LEDR[1],Location,PIN_R19,Yes +,LEDR[2],Location,PIN_U19,Yes +,LEDR[3],Location,PIN_Y19,Yes +,LEDR[4],Location,PIN_T18,Yes +,LEDR[5],Location,PIN_V19,Yes +,LEDR[6],Location,PIN_Y18,Yes +,LEDR[7],Location,PIN_U18,Yes +,LEDR[8],Location,PIN_R18,Yes +,LEDR[9],Location,PIN_R17,Yes +,LEDG[0],Location,PIN_U22,Yes +,LEDG[1],Location,PIN_U21,Yes +,LEDG[2],Location,PIN_V22,Yes +,LEDG[3],Location,PIN_V21,Yes +,LEDG[4],Location,PIN_W22,Yes +,LEDG[5],Location,PIN_W21,Yes +,LEDG[6],Location,PIN_Y22,Yes +,LEDG[7],Location,PIN_Y21,Yes +,KEY[0],I/O Standard,LVTTL,Yes +,KEY[1],I/O Standard,LVTTL,Yes +,KEY[2],I/O Standard,LVTTL,Yes +,KEY[3],I/O Standard,LVTTL,Yes +,LEDR[0],I/O Standard,LVTTL,Yes +,LEDR[1],I/O Standard,LVTTL,Yes +,LEDR[2],I/O Standard,LVTTL,Yes +,LEDR[3],I/O Standard,LVTTL,Yes +,LEDR[4],I/O Standard,LVTTL,Yes +,LEDR[5],I/O Standard,LVTTL,Yes +,LEDR[6],I/O Standard,LVTTL,Yes +,LEDR[7],I/O Standard,LVTTL,Yes +,LEDR[8],I/O Standard,LVTTL,Yes +,LEDR[9],I/O Standard,LVTTL,Yes +,LEDG[0],I/O Standard,LVTTL,Yes +,LEDG[1],I/O Standard,LVTTL,Yes +,LEDG[2],I/O Standard,LVTTL,Yes +,LEDG[3],I/O Standard,LVTTL,Yes +,LEDG[4],I/O Standard,LVTTL,Yes +,LEDG[5],I/O Standard,LVTTL,Yes +,LEDG[6],I/O Standard,LVTTL,Yes +,LEDG[7],I/O Standard,LVTTL,Yes +,CLOCK_27[0],Location,PIN_D12,Yes +,CLOCK_27[1],Location,PIN_E12,Yes +,CLOCK_24[0],Location,PIN_B12,Yes +,CLOCK_24[1],Location,PIN_A12,Yes +,CLOCK_50,Location,PIN_L1,Yes +,EXT_CLOCK,Location,PIN_M21,Yes +,CLOCK_27[1],I/O Standard,LVTTL,Yes +,CLOCK_24[0],I/O Standard,LVTTL,Yes +,CLOCK_24[1],I/O Standard,LVTTL,Yes +,CLOCK_50,I/O Standard,LVTTL,Yes +,EXT_CLOCK,I/O Standard,LVTTL,Yes +,PS2_CLK,Location,PIN_H15,Yes +,PS2_DAT,Location,PIN_J14,Yes +,UART_RXD,Location,PIN_F14,Yes +,UART_TXD,Location,PIN_G12,Yes +,PS2_CLK,I/O Standard,LVTTL,Yes +,PS2_DAT,I/O Standard,LVTTL,Yes +,UART_RXD,I/O Standard,LVTTL,Yes +,UART_TXD,I/O Standard,LVTTL,Yes +,TDI,Location,PIN_E8,Yes +,TCS,Location,PIN_D8,Yes +,TCK,Location,PIN_C7,Yes +,TDO,Location,PIN_D7,Yes +,TDI,I/O Standard,LVTTL,Yes +,TCS,I/O Standard,LVTTL,Yes +,TCK,I/O Standard,LVTTL,Yes +,TDO,I/O Standard,LVTTL,Yes +,VGA_R[0],Location,PIN_D9,Yes +,VGA_R[1],Location,PIN_C9,Yes +,VGA_R[2],Location,PIN_A7,Yes +,VGA_R[3],Location,PIN_B7,Yes +,VGA_G[0],Location,PIN_B8,Yes +,VGA_G[1],Location,PIN_C10,Yes +,VGA_G[2],Location,PIN_B9,Yes +,VGA_G[3],Location,PIN_A8,Yes +,VGA_B[0],Location,PIN_A9,Yes +,VGA_B[1],Location,PIN_D11,Yes +,VGA_B[2],Location,PIN_A10,Yes +,VGA_B[3],Location,PIN_B10,Yes +,VGA_HS,Location,PIN_A11,Yes +,VGA_VS,Location,PIN_B11,Yes +,VGA_R[0],I/O Standard,LVTTL,Yes +,VGA_R[1],I/O Standard,LVTTL,Yes +,VGA_R[2],I/O Standard,LVTTL,Yes +,VGA_R[3],I/O Standard,LVTTL,Yes +,VGA_G[0],I/O Standard,LVTTL,Yes +,VGA_G[1],I/O Standard,LVTTL,Yes +,VGA_G[2],I/O Standard,LVTTL,Yes +,VGA_G[3],I/O Standard,LVTTL,Yes +,VGA_B[0],I/O Standard,LVTTL,Yes +,VGA_B[1],I/O Standard,LVTTL,Yes +,VGA_B[2],I/O Standard,LVTTL,Yes +,VGA_B[3],I/O Standard,LVTTL,Yes +,VGA_HS,I/O Standard,LVTTL,Yes +,VGA_VS,I/O Standard,LVTTL,Yes +,I2C_SCLK,Location,PIN_A3,Yes +,I2C_SDAT,Location,PIN_B3,Yes +,AUD_ADCLRCK,Location,PIN_A6,Yes +,AUD_ADCDAT,Location,PIN_B6,Yes +,AUD_DACLRCK,Location,PIN_A5,Yes +,AUD_DACDAT,Location,PIN_B5,Yes +,AUD_XCK,Location,PIN_B4,Yes +,AUD_BCLK,Location,PIN_A4,Yes +,I2C_SCLK,I/O Standard,LVTTL,Yes +,I2C_SDAT,I/O Standard,LVTTL,Yes +,AUD_ADCLRCK,I/O Standard,LVTTL,Yes +,AUD_ADCDAT,I/O Standard,LVTTL,Yes +,AUD_DACLRCK,I/O Standard,LVTTL,Yes +,AUD_DACDAT,I/O Standard,LVTTL,Yes +,AUD_XCK,I/O Standard,LVTTL,Yes +,AUD_BCLK,I/O Standard,LVTTL,Yes +,DRAM_ADDR[0],Location,PIN_W4,Yes +,DRAM_ADDR[1],Location,PIN_W5,Yes +,DRAM_ADDR[2],Location,PIN_Y3,Yes +,DRAM_ADDR[3],Location,PIN_Y4,Yes +,DRAM_ADDR[4],Location,PIN_R6,Yes +,DRAM_ADDR[5],Location,PIN_R5,Yes +,DRAM_ADDR[6],Location,PIN_P6,Yes +,DRAM_ADDR[7],Location,PIN_P5,Yes +,DRAM_ADDR[8],Location,PIN_P3,Yes +,DRAM_ADDR[9],Location,PIN_N4,Yes +,DRAM_ADDR[10],Location,PIN_W3,Yes +,DRAM_ADDR[11],Location,PIN_N6,Yes +,DRAM_BA_0,Location,PIN_U3,Yes +,DRAM_BA_1,Location,PIN_V4,Yes +,DRAM_CAS_N,Location,PIN_T3,Yes +,DRAM_CKE,Location,PIN_N3,Yes +,DRAM_CLK,Location,PIN_U4,Yes +,DRAM_CS_N,Location,PIN_T6,Yes +,DRAM_DQ[0],Location,PIN_U1,Yes +,DRAM_DQ[1],Location,PIN_U2,Yes +,DRAM_DQ[2],Location,PIN_V1,Yes +,DRAM_DQ[3],Location,PIN_V2,Yes +,DRAM_DQ[4],Location,PIN_W1,Yes +,DRAM_DQ[5],Location,PIN_W2,Yes +,DRAM_DQ[6],Location,PIN_Y1,Yes +,DRAM_DQ[7],Location,PIN_Y2,Yes +,DRAM_DQ[8],Location,PIN_N1,Yes +,DRAM_DQ[9],Location,PIN_N2,Yes +,DRAM_DQ[10],Location,PIN_P1,Yes +,DRAM_DQ[11],Location,PIN_P2,Yes +,DRAM_DQ[12],Location,PIN_R1,Yes +,DRAM_DQ[13],Location,PIN_R2,Yes +,DRAM_DQ[14],Location,PIN_T1,Yes +,DRAM_DQ[15],Location,PIN_T2,Yes +,DRAM_LDQM,Location,PIN_R7,Yes +,DRAM_RAS_N,Location,PIN_T5,Yes +,DRAM_UDQM,Location,PIN_M5,Yes +,DRAM_WE_N,Location,PIN_R8,Yes +,FL_ADDR[0],Location,PIN_AB20,Yes +,FL_ADDR[1],Location,PIN_AA14,Yes +,FL_ADDR[2],Location,PIN_Y16,Yes +,FL_ADDR[3],Location,PIN_R15,Yes +,FL_ADDR[4],Location,PIN_T15,Yes +,FL_ADDR[5],Location,PIN_U15,Yes +,FL_ADDR[6],Location,PIN_V15,Yes +,FL_ADDR[7],Location,PIN_W15,Yes +,FL_ADDR[8],Location,PIN_R14,Yes +,FL_ADDR[9],Location,PIN_Y13,Yes +,FL_ADDR[10],Location,PIN_R12,Yes +,FL_ADDR[11],Location,PIN_T12,Yes +,FL_ADDR[12],Location,PIN_AB14,Yes +,FL_ADDR[13],Location,PIN_AA13,Yes +,FL_ADDR[14],Location,PIN_AB13,Yes +,FL_ADDR[15],Location,PIN_AA12,Yes +,FL_ADDR[16],Location,PIN_AB12,Yes +,FL_ADDR[17],Location,PIN_AA20,Yes +,FL_ADDR[18],Location,PIN_U14,Yes +,FL_ADDR[19],Location,PIN_V14,Yes +,FL_ADDR[20],Location,PIN_U13,Yes +,FL_ADDR[21],Location,PIN_R13,Yes +,FL_DQ[0],Location,PIN_AB16,Yes +,FL_DQ[1],Location,PIN_AA16,Yes +,FL_DQ[2],Location,PIN_AB17,Yes +,FL_DQ[3],Location,PIN_AA17,Yes +,FL_DQ[4],Location,PIN_AB18,Yes +,FL_DQ[5],Location,PIN_AA18,Yes +,FL_DQ[6],Location,PIN_AB19,Yes +,FL_DQ[7],Location,PIN_AA19,Yes +,FL_OE_N,Location,PIN_AA15,Yes +,FL_RST_N,Location,PIN_W14,Yes +,FL_WE_N,Location,PIN_Y14,Yes +,SRAM_ADDR[0],Location,PIN_AA3,Yes +,SRAM_ADDR[1],Location,PIN_AB3,Yes +,SRAM_ADDR[2],Location,PIN_AA4,Yes +,SRAM_ADDR[3],Location,PIN_AB4,Yes +,SRAM_ADDR[4],Location,PIN_AA5,Yes +,SRAM_ADDR[5],Location,PIN_AB10,Yes +,SRAM_ADDR[6],Location,PIN_AA11,Yes +,SRAM_ADDR[7],Location,PIN_AB11,Yes +,SRAM_ADDR[8],Location,PIN_V11,Yes +,SRAM_ADDR[9],Location,PIN_W11,Yes +,SRAM_ADDR[10],Location,PIN_R11,Yes +,SRAM_ADDR[11],Location,PIN_T11,Yes +,SRAM_ADDR[12],Location,PIN_Y10,Yes +,SRAM_ADDR[13],Location,PIN_U10,Yes +,SRAM_ADDR[14],Location,PIN_R10,Yes +,SRAM_ADDR[15],Location,PIN_T7,Yes +,SRAM_ADDR[16],Location,PIN_Y6,Yes +,SRAM_ADDR[17],Location,PIN_Y5,Yes +,SRAM_CE_N,Location,PIN_AB5,Yes +,SRAM_DQ[0],Location,PIN_AA6,Yes +,SRAM_DQ[1],Location,PIN_AB6,Yes +,SRAM_DQ[2],Location,PIN_AA7,Yes +,SRAM_DQ[3],Location,PIN_AB7,Yes +,SRAM_DQ[4],Location,PIN_AA8,Yes +,SRAM_DQ[5],Location,PIN_AB8,Yes +,SRAM_DQ[6],Location,PIN_AA9,Yes +,SRAM_DQ[7],Location,PIN_AB9,Yes +,SRAM_DQ[8],Location,PIN_Y9,Yes +,SRAM_DQ[9],Location,PIN_W9,Yes +,SRAM_DQ[10],Location,PIN_V9,Yes +,SRAM_DQ[11],Location,PIN_U9,Yes +,SRAM_DQ[12],Location,PIN_R9,Yes +,SRAM_DQ[13],Location,PIN_W8,Yes +,SRAM_DQ[14],Location,PIN_V8,Yes +,SRAM_DQ[15],Location,PIN_U8,Yes +,SRAM_LB_N,Location,PIN_Y7,Yes +,SRAM_OE_N,Location,PIN_T8,Yes +,SRAM_UB_N,Location,PIN_W7,Yes +,SRAM_WE_N,Location,PIN_AA10,Yes diff --git a/README b/README new file mode 100644 index 0000000..6da2db8 --- /dev/null +++ b/README @@ -0,0 +1,2 @@ +T65 implementation from http://www.fpgaarcade.com/resources/T65_v302.zip + diff --git a/T65/T65.vhd b/T65/T65.vhd new file mode 100644 index 0000000..f02a5b6 --- /dev/null +++ b/T65/T65.vhd @@ -0,0 +1,551 @@ +-- **** +-- T65(b) core. In an effort to merge and maintain bug fixes .... +-- +-- +-- Ver 301 more merging +-- Ver 300 Bugfixes by ehenciak added, started tidyup *bust* +-- MikeJ March 2005 +-- Latest version from www.fpgaarcade.com (original www.opencores.org) +-- +-- **** +-- +-- 65xx compatible microprocessor core +-- +-- Version : 0246 +-- +-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t65/ +-- +-- Limitations : +-- +-- 65C02 and 65C816 modes are incomplete +-- Undocumented instructions are not supported +-- Some interface signals behaves incorrect +-- +-- File history : +-- +-- 0246 : First release +-- + +library IEEE; + use IEEE.std_logic_1164.all; + use IEEE.numeric_std.all; + use work.T65_Pack.all; + +-- ehenciak 2-23-2005 : Added the enable signal so that one doesn't have to use +-- the ready signal to limit the CPU. +entity T65 is + port( + Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65C816 + Res_n : in std_logic; + Enable : in std_logic; + Clk : in std_logic; + Rdy : in std_logic; + Abort_n : in std_logic; + IRQ_n : in std_logic; + NMI_n : in std_logic; + SO_n : in std_logic; + R_W_n : out std_logic; + Sync : out std_logic; + EF : out std_logic; + MF : out std_logic; + XF : out std_logic; + ML_n : out std_logic; + VP_n : out std_logic; + VDA : out std_logic; + VPA : out std_logic; + A : out std_logic_vector(23 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0) + ); +end T65; + +architecture rtl of T65 is + + -- Registers + signal ABC, X, Y, D : std_logic_vector(15 downto 0); + signal P, AD, DL : std_logic_vector(7 downto 0) := x"00"; + signal BAH : std_logic_vector(7 downto 0); + signal BAL : std_logic_vector(8 downto 0); + signal PBR : std_logic_vector(7 downto 0); + signal DBR : std_logic_vector(7 downto 0); + signal PC : unsigned(15 downto 0); + signal S : unsigned(15 downto 0); + signal EF_i : std_logic; + signal MF_i : std_logic; + signal XF_i : std_logic; + + signal IR : std_logic_vector(7 downto 0); + signal MCycle : std_logic_vector(2 downto 0); + + signal Mode_r : std_logic_vector(1 downto 0); + signal ALU_Op_r : std_logic_vector(3 downto 0); + signal Write_Data_r : std_logic_vector(2 downto 0); + signal Set_Addr_To_r : std_logic_vector(1 downto 0); + signal PCAdder : unsigned(8 downto 0); + + signal RstCycle : std_logic; + signal IRQCycle : std_logic; + signal NMICycle : std_logic; + + signal B_o : std_logic; + signal SO_n_o : std_logic; + signal IRQ_n_o : std_logic; + signal NMI_n_o : std_logic; + signal NMIAct : std_logic; + + signal Break : std_logic; + + -- ALU signals + signal BusA : std_logic_vector(7 downto 0); + signal BusA_r : std_logic_vector(7 downto 0); + signal BusB : std_logic_vector(7 downto 0); + signal ALU_Q : std_logic_vector(7 downto 0); + signal P_Out : std_logic_vector(7 downto 0); + + -- Micro code outputs + signal LCycle : std_logic_vector(2 downto 0); + signal ALU_Op : std_logic_vector(3 downto 0); + signal Set_BusA_To : std_logic_vector(2 downto 0); + signal Set_Addr_To : std_logic_vector(1 downto 0); + signal Write_Data : std_logic_vector(2 downto 0); + signal Jump : std_logic_vector(1 downto 0); + signal BAAdd : std_logic_vector(1 downto 0); + signal BreakAtNA : std_logic; + signal ADAdd : std_logic; + signal AddY : std_logic; + signal PCAdd : std_logic; + signal Inc_S : std_logic; + signal Dec_S : std_logic; + signal LDA : std_logic; + signal LDP : std_logic; + signal LDX : std_logic; + signal LDY : std_logic; + signal LDS : std_logic; + signal LDDI : std_logic; + signal LDALU : std_logic; + signal LDAD : std_logic; + signal LDBAL : std_logic; + signal LDBAH : std_logic; + signal SaveP : std_logic; + signal Write : std_logic; + + signal really_rdy : std_logic; + signal R_W_n_i : std_logic; + +begin + -- ehenciak : gate Rdy with read/write to make an "OK, it's + -- really OK to stop the processor now if Rdy is + -- deasserted" signal + really_rdy <= Rdy or not(R_W_n_i); + + -- ehenciak : Drive R_W_n_i off chip. + R_W_n <= R_W_n_i; + + Sync <= '1' when MCycle = "000" else '0'; + EF <= EF_i; + MF <= MF_i; + XF <= XF_i; + ML_n <= '0' when IR(7 downto 6) /= "10" and IR(2 downto 1) = "11" and MCycle(2 downto 1) /= "00" else '1'; + VP_n <= '0' when IRQCycle = '1' and (MCycle = "101" or MCycle = "110") else '1'; + VDA <= '1' when Set_Addr_To_r /= "000" else '0'; -- Incorrect !!!!!!!!!!!! + VPA <= '1' when Jump(1) = '0' else '0'; -- Incorrect !!!!!!!!!!!! + + mcode : T65_MCode + port map( + Mode => Mode_r, + IR => IR, + MCycle => MCycle, + P => P, + LCycle => LCycle, + ALU_Op => ALU_Op, + Set_BusA_To => Set_BusA_To, + Set_Addr_To => Set_Addr_To, + Write_Data => Write_Data, + Jump => Jump, + BAAdd => BAAdd, + BreakAtNA => BreakAtNA, + ADAdd => ADAdd, + AddY => AddY, + PCAdd => PCAdd, + Inc_S => Inc_S, + Dec_S => Dec_S, + LDA => LDA, + LDP => LDP, + LDX => LDX, + LDY => LDY, + LDS => LDS, + LDDI => LDDI, + LDALU => LDALU, + LDAD => LDAD, + LDBAL => LDBAL, + LDBAH => LDBAH, + SaveP => SaveP, + Write => Write + ); + + alu : T65_ALU + port map( + Mode => Mode_r, + Op => ALU_Op_r, + BusA => BusA_r, + BusB => BusB, + P_In => P, + P_Out => P_Out, + Q => ALU_Q + ); + + process (Res_n, Clk) + begin + if Res_n = '0' then + PC <= (others => '0'); -- Program Counter + IR <= "00000000"; + S <= (others => '0'); -- Dummy !!!!!!!!!!!!!!!!!!!!! + D <= (others => '0'); + PBR <= (others => '0'); + DBR <= (others => '0'); + + Mode_r <= (others => '0'); + ALU_Op_r <= "1100"; + Write_Data_r <= "000"; + Set_Addr_To_r <= "00"; + + R_W_n_i <= '1'; + EF_i <= '1'; + MF_i <= '1'; + XF_i <= '1'; + + elsif Clk'event and Clk = '1' then + if (Enable = '1') then + if (really_rdy = '1') then + R_W_n_i <= not Write or RstCycle; + + D <= (others => '1'); -- Dummy + PBR <= (others => '1'); -- Dummy + DBR <= (others => '1'); -- Dummy + EF_i <= '0'; -- Dummy + MF_i <= '0'; -- Dummy + XF_i <= '0'; -- Dummy + + if MCycle = "000" then + Mode_r <= Mode; + + if IRQCycle = '0' and NMICycle = '0' then + PC <= PC + 1; + end if; + + if IRQCycle = '1' or NMICycle = '1' then + IR <= "00000000"; + else + IR <= DI; + end if; + end if; + + ALU_Op_r <= ALU_Op; + Write_Data_r <= Write_Data; + if Break = '1' then + Set_Addr_To_r <= "00"; + else + Set_Addr_To_r <= Set_Addr_To; + end if; + + if Inc_S = '1' then + S <= S + 1; + end if; + if Dec_S = '1' and RstCycle = '0' then + S <= S - 1; + end if; + if LDS = '1' then + S(7 downto 0) <= unsigned(ALU_Q); + end if; + + if IR = "00000000" and MCycle = "001" and IRQCycle = '0' and NMICycle = '0' then + PC <= PC + 1; + end if; + -- + -- jump control logic + -- + case Jump is + when "01" => + PC <= PC + 1; + + when "10" => + PC <= unsigned(DI & DL); + + when "11" => + if PCAdder(8) = '1' then + if DL(7) = '0' then + PC(15 downto 8) <= PC(15 downto 8) + 1; + else + PC(15 downto 8) <= PC(15 downto 8) - 1; + end if; + end if; + PC(7 downto 0) <= PCAdder(7 downto 0); + + when others => null; + end case; + end if; + end if; + end if; + end process; + + PCAdder <= resize(PC(7 downto 0),9) + resize(unsigned(DL(7) & DL),9) when PCAdd = '1' + else "0" & PC(7 downto 0); + + process (Clk) + begin + if Clk'event and Clk = '1' then + if (Enable = '1') then + if (really_rdy = '1') then + if MCycle = "000" then + if LDA = '1' then + ABC(7 downto 0) <= ALU_Q; + end if; + if LDX = '1' then + X(7 downto 0) <= ALU_Q; + end if; + if LDY = '1' then + Y(7 downto 0) <= ALU_Q; + end if; + if (LDA or LDX or LDY) = '1' then + P <= P_Out; + end if; + end if; + if SaveP = '1' then + P <= P_Out; + end if; + if LDP = '1' then + P <= ALU_Q; + end if; + if IR(4 downto 0) = "11000" then + case IR(7 downto 5) is + when "000" => + P(Flag_C) <= '0'; + when "001" => + P(Flag_C) <= '1'; + when "010" => + P(Flag_I) <= '0'; + when "011" => + P(Flag_I) <= '1'; + when "101" => + P(Flag_V) <= '0'; + when "110" => + P(Flag_D) <= '0'; + when "111" => + P(Flag_D) <= '1'; + when others => + end case; + end if; + if IR = "00000000" and MCycle = "011" and RstCycle = '0' and NMICycle = '0' and IRQCycle = '0' then + P(Flag_B) <= '1'; + end if; + if IR = "00000000" and MCycle = "100" and RstCycle = '0' and (NMICycle = '1' or IRQCycle = '1') then + P(Flag_I) <= '1'; + P(Flag_B) <= B_o; + end if; + if SO_n_o = '1' and SO_n = '0' then + P(Flag_V) <= '1'; + end if; + if RstCycle = '1' and Mode_r /= "00" then + P(Flag_1) <= '1'; + P(Flag_D) <= '0'; + P(Flag_I) <= '1'; + end if; + P(Flag_1) <= '1'; + + B_o <= P(Flag_B); + SO_n_o <= SO_n; + IRQ_n_o <= IRQ_n; + NMI_n_o <= NMI_n; + end if; + end if; + end if; + end process; + +--------------------------------------------------------------------------- +-- +-- Buses +-- +--------------------------------------------------------------------------- + + process (Res_n, Clk) + begin + if Res_n = '0' then + BusA_r <= (others => '0'); + BusB <= (others => '0'); + AD <= (others => '0'); + BAL <= (others => '0'); + BAH <= (others => '0'); + DL <= (others => '0'); + elsif Clk'event and Clk = '1' then + if (Enable = '1') then + if (Rdy = '1') then + BusA_r <= BusA; + BusB <= DI; + + case BAAdd is + when "01" => + -- BA Inc + AD <= std_logic_vector(unsigned(AD) + 1); + BAL <= std_logic_vector(unsigned(BAL) + 1); + when "10" => + -- BA Add + BAL <= std_logic_vector(resize(unsigned(BAL(7 downto 0)),9) + resize(unsigned(BusA),9)); + when "11" => + -- BA Adj + if BAL(8) = '1' then + BAH <= std_logic_vector(unsigned(BAH) + 1); + end if; + when others => + end case; + + -- ehenciak : modified to use Y register as well (bugfix) + if ADAdd = '1' then + if (AddY = '1') then + AD <= std_logic_vector(unsigned(AD) + unsigned(Y(7 downto 0))); + else + AD <= std_logic_vector(unsigned(AD) + unsigned(X(7 downto 0))); + end if; + end if; + + if IR = "00000000" then + BAL <= (others => '1'); + BAH <= (others => '1'); + if RstCycle = '1' then + BAL(2 downto 0) <= "100"; + elsif NMICycle = '1' then + BAL(2 downto 0) <= "010"; + else + BAL(2 downto 0) <= "110"; + end if; + if Set_addr_To_r = "11" then + BAL(0) <= '1'; + end if; + end if; + + + if LDDI = '1' then + DL <= DI; + end if; + if LDALU = '1' then + DL <= ALU_Q; + end if; + if LDAD = '1' then + AD <= DI; + end if; + if LDBAL = '1' then + BAL(7 downto 0) <= DI; + end if; + if LDBAH = '1' then + BAH <= DI; + end if; + end if; + end if; + end if; + end process; + + Break <= (BreakAtNA and not BAL(8)) or (PCAdd and not PCAdder(8)); + + + with Set_BusA_To select + BusA <= DI when "000", + ABC(7 downto 0) when "001", + X(7 downto 0) when "010", + Y(7 downto 0) when "011", + std_logic_vector(S(7 downto 0)) when "100", + P when "101", + (others => '-') when others; + + with Set_Addr_To_r select + A <= "0000000000000001" & std_logic_vector(S(7 downto 0)) when "01", + DBR & "00000000" & AD when "10", + "00000000" & BAH & BAL(7 downto 0) when "11", + PBR & std_logic_vector(PC(15 downto 8)) & std_logic_vector(PCAdder(7 downto 0)) when others; + + with Write_Data_r select + DO <= DL when "000", + ABC(7 downto 0) when "001", + X(7 downto 0) when "010", + Y(7 downto 0) when "011", + std_logic_vector(S(7 downto 0)) when "100", + P when "101", + std_logic_vector(PC(7 downto 0)) when "110", + std_logic_vector(PC(15 downto 8)) when others; + +------------------------------------------------------------------------- +-- +-- Main state machine +-- +------------------------------------------------------------------------- + + process (Res_n, Clk) + begin + if Res_n = '0' then + MCycle <= "001"; + RstCycle <= '1'; + IRQCycle <= '0'; + NMICycle <= '0'; + NMIAct <= '0'; + elsif Clk'event and Clk = '1' then + if (Enable = '1') then + if (really_rdy = '1') then + if MCycle = LCycle or Break = '1' then + MCycle <= "000"; + RstCycle <= '0'; + IRQCycle <= '0'; + NMICycle <= '0'; + if NMIAct = '1' then + NMICycle <= '1'; + elsif IRQ_n_o = '0' and P(Flag_I) = '0' then + IRQCycle <= '1'; + end if; + else + MCycle <= std_logic_vector(unsigned(MCycle) + 1); + end if; + + if NMICycle = '1' then + NMIAct <= '0'; + end if; + if NMI_n_o = '1' and NMI_n = '0' then + NMIAct <= '1'; + end if; + end if; + end if; + end if; + end process; + +end; diff --git a/T65/T65_ALU.vhd b/T65/T65_ALU.vhd new file mode 100644 index 0000000..d9d25e1 --- /dev/null +++ b/T65/T65_ALU.vhd @@ -0,0 +1,260 @@ +-- **** +-- T65(b) core. In an effort to merge and maintain bug fixes .... +-- +-- +-- Ver 300 Bugfixes by ehenciak added +-- MikeJ March 2005 +-- Latest version from www.fpgaarcade.com (original www.opencores.org) +-- +-- **** +-- +-- 6502 compatible microprocessor core +-- +-- Version : 0245 +-- +-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t65/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0245 : First version +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T65_Pack.all; + +entity T65_ALU is + port( + Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816 + Op : in std_logic_vector(3 downto 0); + BusA : in std_logic_vector(7 downto 0); + BusB : in std_logic_vector(7 downto 0); + P_In : in std_logic_vector(7 downto 0); + P_Out : out std_logic_vector(7 downto 0); + Q : out std_logic_vector(7 downto 0) + ); +end T65_ALU; + +architecture rtl of T65_ALU is + + -- AddSub variables (temporary signals) + signal ADC_Z : std_logic; + signal ADC_C : std_logic; + signal ADC_V : std_logic; + signal ADC_N : std_logic; + signal ADC_Q : std_logic_vector(7 downto 0); + signal SBC_Z : std_logic; + signal SBC_C : std_logic; + signal SBC_V : std_logic; + signal SBC_N : std_logic; + signal SBC_Q : std_logic_vector(7 downto 0); + +begin + + process (P_In, BusA, BusB) + variable AL : unsigned(6 downto 0); + variable AH : unsigned(6 downto 0); + variable C : std_logic; + begin + AL := resize(unsigned(BusA(3 downto 0) & P_In(Flag_C)), 7) + resize(unsigned(BusB(3 downto 0) & "1"), 7); + AH := resize(unsigned(BusA(7 downto 4) & AL(5)), 7) + resize(unsigned(BusB(7 downto 4) & "1"), 7); + +-- pragma translate_off + if is_x(std_logic_vector(AL)) then AL := "0000000"; end if; + if is_x(std_logic_vector(AH)) then AH := "0000000"; end if; +-- pragma translate_on + + if AL(4 downto 1) = 0 and AH(4 downto 1) = 0 then + ADC_Z <= '1'; + else + ADC_Z <= '0'; + end if; + + if AL(5 downto 1) > 9 and P_In(Flag_D) = '1' then + AL(6 downto 1) := AL(6 downto 1) + 6; + end if; + + C := AL(6) or AL(5); + AH := resize(unsigned(BusA(7 downto 4) & C), 7) + resize(unsigned(BusB(7 downto 4) & "1"), 7); + + ADC_N <= AH(4); + ADC_V <= (AH(4) xor BusA(7)) and not (BusA(7) xor BusB(7)); + +-- pragma translate_off + if is_x(std_logic_vector(AH)) then AH := "0000000"; end if; +-- pragma translate_on + + if AH(5 downto 1) > 9 and P_In(Flag_D) = '1' then + AH(6 downto 1) := AH(6 downto 1) + 6; + end if; + + ADC_C <= AH(6) or AH(5); + + ADC_Q <= std_logic_vector(AH(4 downto 1) & AL(4 downto 1)); + end process; + + process (Op, P_In, BusA, BusB) + variable AL : unsigned(6 downto 0); + variable AH : unsigned(5 downto 0); + variable C : std_logic; + begin + C := P_In(Flag_C) or not Op(0); + AL := resize(unsigned(BusA(3 downto 0) & C), 7) - resize(unsigned(BusB(3 downto 0) & "1"), 6); + AH := resize(unsigned(BusA(7 downto 4) & "0"), 6) - resize(unsigned(BusB(7 downto 4) & AL(5)), 6); + +-- pragma translate_off + if is_x(std_logic_vector(AL)) then AL := "0000000"; end if; + if is_x(std_logic_vector(AH)) then AH := "000000"; end if; +-- pragma translate_on + + if AL(4 downto 1) = 0 and AH(4 downto 1) = 0 then + SBC_Z <= '1'; + else + SBC_Z <= '0'; + end if; + + SBC_C <= not AH(5); + SBC_V <= (AH(4) xor BusA(7)) and (BusA(7) xor BusB(7)); + SBC_N <= AH(4); + + if P_In(Flag_D) = '1' then + if AL(5) = '1' then + AL(5 downto 1) := AL(5 downto 1) - 6; + end if; + AH := resize(unsigned(BusA(7 downto 4) & "0"), 6) - resize(unsigned(BusB(7 downto 4) & AL(6)), 6); + if AH(5) = '1' then + AH(5 downto 1) := AH(5 downto 1) - 6; + end if; + end if; + + SBC_Q <= std_logic_vector(AH(4 downto 1) & AL(4 downto 1)); + end process; + + process (Op, P_In, BusA, BusB, + ADC_Z, ADC_C, ADC_V, ADC_N, ADC_Q, + SBC_Z, SBC_C, SBC_V, SBC_N, SBC_Q) + variable Q_t : std_logic_vector(7 downto 0); + begin + -- ORA, AND, EOR, ADC, NOP, LD, CMP, SBC + -- ASL, ROL, LSR, ROR, BIT, LD, DEC, INC + P_Out <= P_In; + Q_t := BusA; + case Op(3 downto 0) is + when "0000" => + -- ORA + Q_t := BusA or BusB; + when "0001" => + -- AND + Q_t := BusA and BusB; + when "0010" => + -- EOR + Q_t := BusA xor BusB; + when "0011" => + -- ADC + P_Out(Flag_V) <= ADC_V; + P_Out(Flag_C) <= ADC_C; + Q_t := ADC_Q; + when "0101" | "1101" => + -- LDA + when "0110" => + -- CMP + P_Out(Flag_C) <= SBC_C; + when "0111" => + -- SBC + P_Out(Flag_V) <= SBC_V; + P_Out(Flag_C) <= SBC_C; + Q_t := SBC_Q; + when "1000" => + -- ASL + Q_t := BusA(6 downto 0) & "0"; + P_Out(Flag_C) <= BusA(7); + when "1001" => + -- ROL + Q_t := BusA(6 downto 0) & P_In(Flag_C); + P_Out(Flag_C) <= BusA(7); + when "1010" => + -- LSR + Q_t := "0" & BusA(7 downto 1); + P_Out(Flag_C) <= BusA(0); + when "1011" => + -- ROR + Q_t := P_In(Flag_C) & BusA(7 downto 1); + P_Out(Flag_C) <= BusA(0); + when "1100" => + -- BIT + P_Out(Flag_V) <= BusB(6); + when "1110" => + -- DEC + Q_t := std_logic_vector(unsigned(BusA) - 1); + when "1111" => + -- INC + Q_t := std_logic_vector(unsigned(BusA) + 1); + when others => + end case; + + case Op(3 downto 0) is + when "0011" => + P_Out(Flag_N) <= ADC_N; + P_Out(Flag_Z) <= ADC_Z; + when "0110" | "0111" => + P_Out(Flag_N) <= SBC_N; + P_Out(Flag_Z) <= SBC_Z; + when "0100" => + when "1100" => + P_Out(Flag_N) <= BusB(7); + if (BusA and BusB) = "00000000" then + P_Out(Flag_Z) <= '1'; + else + P_Out(Flag_Z) <= '0'; + end if; + when others => + P_Out(Flag_N) <= Q_t(7); + if Q_t = "00000000" then + P_Out(Flag_Z) <= '1'; + else + P_Out(Flag_Z) <= '0'; + end if; + end case; + + Q <= Q_t; + end process; + +end; diff --git a/T65/T65_MCode.vhd b/T65/T65_MCode.vhd new file mode 100644 index 0000000..3fd40d8 --- /dev/null +++ b/T65/T65_MCode.vhd @@ -0,0 +1,1052 @@ +-- **** +-- T65(b) core. In an effort to merge and maintain bug fixes .... +-- +-- +-- Ver 302 minor timing fixes +-- Ver 301 Jump timing fixed +-- Ver 300 Bugfixes by ehenciak added +-- MikeJ March 2005 +-- Latest version from www.fpgaarcade.com (original www.opencores.org) +-- +-- **** +-- +-- 65xx compatible microprocessor core +-- +-- Version : 0246 + fix +-- +-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t65/ +-- +-- Limitations : +-- +-- 65C02 +-- supported : inc, dec, phx, plx, phy, ply +-- missing : bra, ora, lda, cmp, sbc, tsb*2, trb*2, stz*2, bit*2, wai, stp, jmp, bbr*8, bbs*8 +-- +-- File history : +-- +-- 0246 : First release +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T65_Pack.all; + +entity T65_MCode is + port( + Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816 + IR : in std_logic_vector(7 downto 0); + MCycle : in std_logic_vector(2 downto 0); + P : in std_logic_vector(7 downto 0); + LCycle : out std_logic_vector(2 downto 0); + ALU_Op : out std_logic_vector(3 downto 0); + Set_BusA_To : out std_logic_vector(2 downto 0); -- DI,A,X,Y,S,P + Set_Addr_To : out std_logic_vector(1 downto 0); -- PC Adder,S,AD,BA + Write_Data : out std_logic_vector(2 downto 0); -- DL,A,X,Y,S,P,PCL,PCH + Jump : out std_logic_vector(1 downto 0); -- PC,++,DIDL,Rel + BAAdd : out std_logic_vector(1 downto 0); -- None,DB Inc,BA Add,BA Adj + BreakAtNA : out std_logic; + ADAdd : out std_logic; + AddY : out std_logic; + PCAdd : out std_logic; + Inc_S : out std_logic; + Dec_S : out std_logic; + LDA : out std_logic; + LDP : out std_logic; + LDX : out std_logic; + LDY : out std_logic; + LDS : out std_logic; + LDDI : out std_logic; + LDALU : out std_logic; + LDAD : out std_logic; + LDBAL : out std_logic; + LDBAH : out std_logic; + SaveP : out std_logic; + Write : out std_logic + ); +end T65_MCode; + +architecture rtl of T65_MCode is + + signal Branch : std_logic; + +begin + + with IR(7 downto 5) select + Branch <= not P(Flag_N) when "000", + P(Flag_N) when "001", + not P(Flag_V) when "010", + P(Flag_V) when "011", + not P(Flag_C) when "100", + P(Flag_C) when "101", + not P(Flag_Z) when "110", + P(Flag_Z) when others; + + process (IR, MCycle, P, Branch, Mode) + begin + LCycle <= "001"; + Set_BusA_To <= "001"; -- A + Set_Addr_To <= (others => '0'); + Write_Data <= (others => '0'); + Jump <= (others => '0'); + BAAdd <= "00"; + BreakAtNA <= '0'; + ADAdd <= '0'; + PCAdd <= '0'; + Inc_S <= '0'; + Dec_S <= '0'; + LDA <= '0'; + LDP <= '0'; + LDX <= '0'; + LDY <= '0'; + LDS <= '0'; + LDDI <= '0'; + LDALU <= '0'; + LDAD <= '0'; + LDBAL <= '0'; + LDBAH <= '0'; + SaveP <= '0'; + Write <= '0'; + AddY <= '0'; + + case IR(7 downto 5) is + when "100" => + --{{{ + case IR(1 downto 0) is + when "00" => + Set_BusA_To <= "011"; -- Y + Write_Data <= "011"; -- Y + when "10" => + Set_BusA_To <= "010"; -- X + Write_Data <= "010"; -- X + when others => + Write_Data <= "001"; -- A + end case; + --}}} + when "101" => + --{{{ + case IR(1 downto 0) is + when "00" => + if IR(4) /= '1' or IR(2) /= '0' then + LDY <= '1'; + end if; + when "10" => + LDX <= '1'; + when others => + LDA <= '1'; + end case; + Set_BusA_To <= "000"; -- DI + --}}} + when "110" => + --{{{ + case IR(1 downto 0) is + when "00" => + if IR(4) = '0' then + LDY <= '1'; + end if; + Set_BusA_To <= "011"; -- Y + when others => + Set_BusA_To <= "001"; -- A + end case; + --}}} + when "111" => + --{{{ + case IR(1 downto 0) is + when "00" => + if IR(4) = '0' then + LDX <= '1'; + end if; + Set_BusA_To <= "010"; -- X + when others => + Set_BusA_To <= "001"; -- A + end case; + --}}} + when others => + end case; + + if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then + Set_BusA_To <= "000"; -- DI + end if; + + case IR(4 downto 0) is + when "00000" | "01000" | "01010" | "11000" | "11010" => + --{{{ + -- Implied + case IR is + when "00000000" => + -- BRK + LCycle <= "110"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= "01"; -- S + Write_Data <= "111"; -- PCH + Write <= '1'; + when 2 => + Dec_S <= '1'; + Set_Addr_To <= "01"; -- S + Write_Data <= "110"; -- PCL + Write <= '1'; + when 3 => + Dec_S <= '1'; + Set_Addr_To <= "01"; -- S + Write_Data <= "101"; -- P + Write <= '1'; + when 4 => + Dec_S <= '1'; + Set_Addr_To <= "11"; -- BA + when 5 => + LDDI <= '1'; + Set_Addr_To <= "11"; -- BA + when 6 => + Jump <= "10"; -- DIDL + when others => + end case; + when "00100000" => + -- JSR + LCycle <= "101"; + case to_integer(unsigned(MCycle)) is + when 1 => + Jump <= "01"; + LDDI <= '1'; + Set_Addr_To <= "01"; -- S + when 2 => + Set_Addr_To <= "01"; -- S + Write_Data <= "111"; -- PCH + Write <= '1'; + when 3 => + Dec_S <= '1'; + Set_Addr_To <= "01"; -- S + Write_Data <= "110"; -- PCL + Write <= '1'; + when 4 => + Dec_S <= '1'; + when 5 => + Jump <= "10"; -- DIDL + when others => + end case; + when "01000000" => + -- RTI + LCycle <= "101"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= "01"; -- S + when 2 => + Inc_S <= '1'; + Set_Addr_To <= "01"; -- S + when 3 => + Inc_S <= '1'; + Set_Addr_To <= "01"; -- S + Set_BusA_To <= "000"; -- DI + when 4 => + LDP <= '1'; + Inc_S <= '1'; + LDDI <= '1'; + Set_Addr_To <= "01"; -- S + when 5 => + Jump <= "10"; -- DIDL + when others => + end case; + when "01100000" => + -- RTS + LCycle <= "101"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= "01"; -- S + when 2 => + Inc_S <= '1'; + Set_Addr_To <= "01"; -- S + when 3 => + Inc_S <= '1'; + LDDI <= '1'; + Set_Addr_To <= "01"; -- S + when 4 => + Jump <= "10"; -- DIDL + when 5 => + Jump <= "01"; + when others => + end case; + when "00001000" | "01001000" | "01011010" | "11011010" => + -- PHP, PHA, PHY*, PHX* + LCycle <= "010"; + if Mode = "00" and IR(1) = '1' then + LCycle <= "001"; + end if; + case to_integer(unsigned(MCycle)) is + when 1 => + case IR(7 downto 4) is + when "0000" => + Write_Data <= "101"; -- P + when "0100" => + Write_Data <= "001"; -- A + when "0101" => + Write_Data <= "011"; -- Y + when "1101" => + Write_Data <= "010"; -- X + when others => + end case; + Write <= '1'; + Set_Addr_To <= "01"; -- S + when 2 => + Dec_S <= '1'; + when others => + end case; + when "00101000" | "01101000" | "01111010" | "11111010" => + -- PLP, PLA, PLY*, PLX* + LCycle <= "011"; + if Mode = "00" and IR(1) = '1' then + LCycle <= "001"; + end if; + case IR(7 downto 4) is + when "0010" => + LDP <= '1'; + when "0110" => + LDA <= '1'; + when "0111" => + if Mode /= "00" then + LDY <= '1'; + end if; + when "1111" => + if Mode /= "00" then + LDX <= '1'; + end if; + when others => + end case; + case to_integer(unsigned(MCycle)) is + when 0 => + SaveP <= '1'; + when 1 => + Set_Addr_To <= "01"; -- S + when 2 => + Inc_S <= '1'; + Set_Addr_To <= "01"; -- S + when 3 => + Set_BusA_To <= "000"; -- DI + when others => + end case; + when "10100000" | "11000000" | "11100000" => + -- LDY, CPY, CPX + -- Immediate + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Jump <= "01"; + when others => + end case; + when "10001000" => + -- DEY + LDY <= '1'; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Set_BusA_To <= "011"; -- Y + when others => + end case; + when "11001010" => + -- DEX + LDX <= '1'; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Set_BusA_To <= "010"; -- X + when others => + end case; + when "00011010" | "00111010" => + -- INC*, DEC* + if Mode /= "00" then + LDA <= '1'; -- A + end if; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Set_BusA_To <= "100"; -- S + when others => + end case; + when "00001010" | "00101010" | "01001010" | "01101010" => + -- ASL, ROL, LSR, ROR + LDA <= '1'; -- A + Set_BusA_To <= "001"; -- A + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + when others => + end case; + when "10001010" | "10011000" => + -- TYA, TXA + LDA <= '1'; -- A + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + when others => + end case; + when "10101010" | "10101000" => + -- TAX, TAY + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Set_BusA_To <= "001"; -- A + when others => + end case; + when "10011010" => + -- TXS + case to_integer(unsigned(MCycle)) is + when 0 => + LDS <= '1'; + when 1 => + when others => + end case; + when "10111010" => + -- TSX + LDX <= '1'; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Set_BusA_To <= "100"; -- S + when others => + end case; + + -- when "00011000" | "00111000" | "01011000" | "01111000" | "10111000" | "11011000" | "11111000" | "11001000" | "11101000" => + -- -- CLC, SEC, CLI, SEI, CLV, CLD, SED, INY, INX + -- case to_integer(unsigned(MCycle)) is + -- when 1 => + -- when others => + -- end case; + when others => + case to_integer(unsigned(MCycle)) is + when 0 => + when others => + end case; + end case; + --}}} + + when "00001" | "00011" => + --{{{ + -- Zero Page Indexed Indirect (d,x) + LCycle <= "101"; + if IR(7 downto 6) /= "10" then + LDA <= '1'; + end if; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Jump <= "01"; + LDAD <= '1'; + Set_Addr_To <= "10"; -- AD + when 2 => + ADAdd <= '1'; + Set_Addr_To <= "10"; -- AD + when 3 => + BAAdd <= "01"; -- DB Inc + LDBAL <= '1'; + Set_Addr_To <= "10"; -- AD + when 4 => + LDBAH <= '1'; + if IR(7 downto 5) = "100" then + Write <= '1'; + end if; + Set_Addr_To <= "11"; -- BA + when 5 => + when others => + end case; + --}}} + + when "01001" | "01011" => + --{{{ + -- Immediate + LDA <= '1'; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Jump <= "01"; + when others => + end case; + + --}}} + + when "00010" | "10010" => + --{{{ + -- Immediate, KIL + LDX <= '1'; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + if IR = "10100010" then + -- LDX + Jump <= "01"; + else + -- KIL !!!!!!!!!!!!!!!!!!!!!!!!!!!!! + end if; + when others => + end case; + --}}} + + when "00100" => + --{{{ + -- Zero Page + LCycle <= "010"; + case to_integer(unsigned(MCycle)) is + when 0 => + if IR(7 downto 5) = "001" then + SaveP <= '1'; + end if; + when 1 => + Jump <= "01"; + LDAD <= '1'; + if IR(7 downto 5) = "100" then + Write <= '1'; + end if; + Set_Addr_To <= "10"; -- AD + when 2 => + when others => + end case; + --}}} + + when "00101" | "00110" | "00111" => + --{{{ + -- Zero Page + if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then + -- Read-Modify-Write + LCycle <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + Jump <= "01"; + LDAD <= '1'; + Set_Addr_To <= "10"; -- AD + when 2 => + LDDI <= '1'; + Write <= '1'; + Set_Addr_To <= "10"; -- AD + when 3 => + LDALU <= '1'; + SaveP <= '1'; + Write <= '1'; + Set_Addr_To <= "10"; -- AD + when 4 => + when others => + end case; + else + LCycle <= "010"; + if IR(7 downto 6) /= "10" then + LDA <= '1'; + end if; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Jump <= "01"; + LDAD <= '1'; + if IR(7 downto 5) = "100" then + Write <= '1'; + end if; + Set_Addr_To <= "10"; -- AD + when 2 => + when others => + end case; + end if; + --}}} + + when "01100" => + --{{{ + -- Absolute + if IR(7 downto 6) = "01" and IR(4 downto 0) = "01100" then + -- JMP + if IR(5) = '0' then + --LCycle <= "011"; + LCycle <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Jump <= "01"; + LDDI <= '1'; + when 2 => + Jump <= "10"; -- DIDL + when others => + end case; + else + --LCycle <= "101"; + LCycle <= "100"; -- mikej + case to_integer(unsigned(MCycle)) is + when 1 => + Jump <= "01"; + LDDI <= '1'; + LDBAL <= '1'; + when 2 => + LDBAH <= '1'; + if Mode /= "00" then + Jump <= "10"; -- DIDL + end if; + if Mode = "00" then + Set_Addr_To <= "11"; -- BA + end if; + when 3 => + LDDI <= '1'; + if Mode = "00" then + Set_Addr_To <= "11"; -- BA + BAAdd <= "01"; -- DB Inc + else + Jump <= "01"; + end if; + when 4 => + Jump <= "10"; -- DIDL + when others => + end case; + end if; + else + LCycle <= "011"; + case to_integer(unsigned(MCycle)) is + when 0 => + if IR(7 downto 5) = "001" then + SaveP <= '1'; + end if; + when 1 => + Jump <= "01"; + LDBAL <= '1'; + when 2 => + Jump <= "01"; + LDBAH <= '1'; + if IR(7 downto 5) = "100" then + Write <= '1'; + end if; + Set_Addr_To <= "11"; -- BA + when 3 => + when others => + end case; + end if; + --}}} + + when "01101" | "01110" | "01111" => + --{{{ + -- Absolute + if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then + -- Read-Modify-Write + LCycle <= "101"; + case to_integer(unsigned(MCycle)) is + when 1 => + Jump <= "01"; + LDBAL <= '1'; + when 2 => + Jump <= "01"; + LDBAH <= '1'; + Set_Addr_To <= "11"; -- BA + when 3 => + LDDI <= '1'; + Write <= '1'; + Set_Addr_To <= "11"; -- BA + when 4 => + Write <= '1'; + LDALU <= '1'; + SaveP <= '1'; + Set_Addr_To <= "11"; -- BA + when 5 => + SaveP <= '0'; -- MIKEJ was 1 + when others => + end case; + else + LCycle <= "011"; + if IR(7 downto 6) /= "10" then + LDA <= '1'; + end if; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Jump <= "01"; + LDBAL <= '1'; + when 2 => + Jump <= "01"; + LDBAH <= '1'; + if IR(7 downto 5) = "100" then + Write <= '1'; + end if; + Set_Addr_To <= "11"; -- BA + when 3 => + when others => + end case; + end if; + --}}} + + when "10000" => + --{{{ + -- Relative + + -- This circuit dictates when the last + -- microcycle occurs for the branch depending on + -- whether or not the branch is taken and if a page + -- is crossed... + if (Branch = '1') then + + LCycle <= "011"; -- We're done @ T3 if branching...upper + -- level logic will stop at T2 if no page cross + -- (See the Break signal) + else + + LCycle <= "001"; + + end if; + + -- This decodes the current microcycle and takes the + -- proper course of action... + case to_integer(unsigned(MCycle)) is + + -- On the T1 microcycle, increment the program counter + -- and instruct the upper level logic to fetch the offset + -- from the Din bus and store it in the data latches. This + -- will be the last microcycle if the branch isn't taken. + when 1 => + + Jump <= "01"; -- Increments the PC by one (PC will now be PC+2) + -- from microcycle T0. + + LDDI <= '1'; -- Tells logic in top level (T65.vhd) to route + -- the Din bus to the memory data latch (DL) + -- so that the branch offset is fetched. + + -- In microcycle T2, tell the logic in the top level to + -- add the offset. If the most significant byte of the + -- program counter (i.e. the current "page") does not need + -- updating, we are done here...the Break signal at the + -- T65.vhd level takes care of that... + when 2 => + + Jump <= "11"; -- Tell the PC Jump logic to use relative mode. + + PCAdd <= '1'; -- This tells the PC adder to update itself with + -- the current offset recently fetched from + -- memory. + + -- The following is microcycle T3 : + -- The program counter should be completely updated + -- on this cycle after the page cross is detected. + -- We don't need to do anything here... + when 3 => + + + when others => null; -- Do nothing. + + end case; + --}}} + + when "10001" | "10011" => + --{{{ + -- Zero Page Indirect Indexed (d),y + LCycle <= "101"; + if IR(7 downto 6) /= "10" then + LDA <= '1'; + end if; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Jump <= "01"; + LDAD <= '1'; + Set_Addr_To <= "10"; -- AD + when 2 => + LDBAL <= '1'; + BAAdd <= "01"; -- DB Inc + Set_Addr_To <= "10"; -- AD + when 3 => + Set_BusA_To <= "011"; -- Y + BAAdd <= "10"; -- BA Add + LDBAH <= '1'; + Set_Addr_To <= "11"; -- BA + when 4 => + BAAdd <= "11"; -- BA Adj + if IR(7 downto 5) = "100" then + Write <= '1'; + else + BreakAtNA <= '1'; + end if; + Set_Addr_To <= "11"; -- BA + when 5 => + when others => + end case; + --}}} + + when "10100" | "10101" | "10110" | "10111" => + --{{{ + -- Zero Page, X + if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then + -- Read-Modify-Write + LCycle <= "101"; + case to_integer(unsigned(MCycle)) is + when 1 => + Jump <= "01"; + LDAD <= '1'; + Set_Addr_To <= "10"; -- AD + when 2 => + ADAdd <= '1'; + Set_Addr_To <= "10"; -- AD + when 3 => + LDDI <= '1'; + Write <= '1'; + Set_Addr_To <= "10"; -- AD + when 4 => + LDALU <= '1'; + SaveP <= '1'; + Write <= '1'; + Set_Addr_To <= "10"; -- AD + when 5 => + when others => + end case; + else + LCycle <= "011"; + if IR(7 downto 6) /= "10" then + LDA <= '1'; + end if; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Jump <= "01"; + LDAD <= '1'; + Set_Addr_To <= "10"; -- AD + when 2 => + ADAdd <= '1'; + -- Added this check for Y reg. use... + if (IR(3 downto 0) = "0110") then + AddY <= '1'; + end if; + + if IR(7 downto 5) = "100" then + Write <= '1'; + end if; + Set_Addr_To <= "10"; -- AD + when 3 => null; + when others => + end case; + end if; + --}}} + + when "11001" | "11011" => + --{{{ + -- Absolute Y + LCycle <= "100"; + if IR(7 downto 6) /= "10" then + LDA <= '1'; + end if; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Jump <= "01"; + LDBAL <= '1'; + when 2 => + Jump <= "01"; + Set_BusA_To <= "011"; -- Y + BAAdd <= "10"; -- BA Add + LDBAH <= '1'; + Set_Addr_To <= "11"; -- BA + when 3 => + BAAdd <= "11"; -- BA adj + if IR(7 downto 5) = "100" then + Write <= '1'; + else + BreakAtNA <= '1'; + end if; + Set_Addr_To <= "11"; -- BA + when 4 => + when others => + end case; + --}}} + + when "11100" | "11101" | "11110" | "11111" => + --{{{ + -- Absolute X + + if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then + -- Read-Modify-Write + LCycle <= "110"; + case to_integer(unsigned(MCycle)) is + when 1 => + Jump <= "01"; + LDBAL <= '1'; + when 2 => + Jump <= "01"; + Set_BusA_To <= "010"; -- X + BAAdd <= "10"; -- BA Add + LDBAH <= '1'; + Set_Addr_To <= "11"; -- BA + when 3 => + BAAdd <= "11"; -- BA adj + Set_Addr_To <= "11"; -- BA + when 4 => + LDDI <= '1'; + Write <= '1'; + Set_Addr_To <= "11"; -- BA + when 5 => + LDALU <= '1'; + SaveP <= '1'; + Write <= '1'; + Set_Addr_To <= "11"; -- BA + when 6 => + when others => + end case; + else + LCycle <= "100"; + if IR(7 downto 6) /= "10" then + LDA <= '1'; + end if; + case to_integer(unsigned(MCycle)) is + when 0 => + when 1 => + Jump <= "01"; + LDBAL <= '1'; + when 2 => + Jump <= "01"; + -- mikej + -- special case 0xBE which uses Y reg as index!! + if (IR = "10111110") then + Set_BusA_To <= "011"; -- Y + else + Set_BusA_To <= "010"; -- X + end if; + BAAdd <= "10"; -- BA Add + LDBAH <= '1'; + Set_Addr_To <= "11"; -- BA + when 3 => + BAAdd <= "11"; -- BA adj + if IR(7 downto 5) = "100" then + Write <= '1'; + else + BreakAtNA <= '1'; + end if; + Set_Addr_To <= "11"; -- BA + when 4 => + when others => + end case; + end if; + --}}} + when others => + end case; + end process; + + process (IR, MCycle) + begin + -- ORA, AND, EOR, ADC, NOP, LD, CMP, SBC + -- ASL, ROL, LSR, ROR, BIT, LD, DEC, INC + case IR(1 downto 0) is + when "00" => + --{{{ + case IR(4 downto 2) is + when "000" | "001" | "011" => + case IR(7 downto 5) is + when "110" | "111" => + -- CP + ALU_Op <= "0110"; + when "101" => + -- LD + ALU_Op <= "0101"; + when "001" => + -- BIT + ALU_Op <= "1100"; + when others => + -- NOP/ST + ALU_Op <= "0100"; + end case; + when "010" => + case IR(7 downto 5) is + when "111" | "110" => + -- IN + ALU_Op <= "1111"; + when "100" => + -- DEY + ALU_Op <= "1110"; + when others => + -- LD + ALU_Op <= "1101"; + end case; + when "110" => + case IR(7 downto 5) is + when "100" => + -- TYA + ALU_Op <= "1101"; + when others => + ALU_Op <= "----"; + end case; + when others => + case IR(7 downto 5) is + when "101" => + -- LD + ALU_Op <= "1101"; + when others => + ALU_Op <= "0100"; + end case; + end case; + --}}} + when "01" => -- OR + --{{{ + ALU_Op(3) <= '0'; + ALU_Op(2 downto 0) <= IR(7 downto 5); + --}}} + when "10" => + --{{{ + ALU_Op(3) <= '1'; + ALU_Op(2 downto 0) <= IR(7 downto 5); + case IR(7 downto 5) is + when "000" => + if IR(4 downto 2) = "110" then + -- INC + ALU_Op <= "1111"; + end if; + when "001" => + if IR(4 downto 2) = "110" then + -- DEC + ALU_Op <= "1110"; + end if; + when "100" => + if IR(4 downto 2) = "010" then + -- TXA + ALU_Op <= "0101"; + else + ALU_Op <= "0100"; + end if; + when others => + end case; + --}}} + when others => + --{{{ + case IR(7 downto 5) is + when "100" => + ALU_Op <= "0100"; + when others => + if MCycle = "000" then + ALU_Op(3) <= '0'; + ALU_Op(2 downto 0) <= IR(7 downto 5); + else + ALU_Op(3) <= '1'; + ALU_Op(2 downto 0) <= IR(7 downto 5); + end if; + end case; + --}}} + end case; + end process; + +end; diff --git a/T65/T65_Pack.vhd b/T65/T65_Pack.vhd new file mode 100644 index 0000000..f8d603c --- /dev/null +++ b/T65/T65_Pack.vhd @@ -0,0 +1,117 @@ +-- **** +-- T65(b) core. In an effort to merge and maintain bug fixes .... +-- +-- +-- Ver 300 Bugfixes by ehenciak added +-- MikeJ March 2005 +-- Latest version from www.fpgaarcade.com (original www.opencores.org) +-- +-- **** +-- +-- 65xx compatible microprocessor core +-- +-- Version : 0246 +-- +-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t65/ +-- +-- Limitations : +-- +-- File history : +-- + +library IEEE; +use IEEE.std_logic_1164.all; + +package T65_Pack is + + constant Flag_C : integer := 0; + constant Flag_Z : integer := 1; + constant Flag_I : integer := 2; + constant Flag_D : integer := 3; + constant Flag_B : integer := 4; + constant Flag_1 : integer := 5; + constant Flag_V : integer := 6; + constant Flag_N : integer := 7; + + component T65_MCode + port( + Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816 + IR : in std_logic_vector(7 downto 0); + MCycle : in std_logic_vector(2 downto 0); + P : in std_logic_vector(7 downto 0); + LCycle : out std_logic_vector(2 downto 0); + ALU_Op : out std_logic_vector(3 downto 0); + Set_BusA_To : out std_logic_vector(2 downto 0); -- DI,A,X,Y,S,P + Set_Addr_To : out std_logic_vector(1 downto 0); -- PC Adder,S,AD,BA + Write_Data : out std_logic_vector(2 downto 0); -- DL,A,X,Y,S,P,PCL,PCH + Jump : out std_logic_vector(1 downto 0); -- PC,++,DIDL,Rel + BAAdd : out std_logic_vector(1 downto 0); -- None,DB Inc,BA Add,BA Adj + BreakAtNA : out std_logic; + ADAdd : out std_logic; + AddY : out std_logic; + PCAdd : out std_logic; + Inc_S : out std_logic; + Dec_S : out std_logic; + LDA : out std_logic; + LDP : out std_logic; + LDX : out std_logic; + LDY : out std_logic; + LDS : out std_logic; + LDDI : out std_logic; + LDALU : out std_logic; + LDAD : out std_logic; + LDBAL : out std_logic; + LDBAH : out std_logic; + SaveP : out std_logic; + Write : out std_logic + ); + end component; + + component T65_ALU + port( + Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65C816 + Op : in std_logic_vector(3 downto 0); + BusA : in std_logic_vector(7 downto 0); + BusB : in std_logic_vector(7 downto 0); + P_In : in std_logic_vector(7 downto 0); + P_Out : out std_logic_vector(7 downto 0); + Q : out std_logic_vector(7 downto 0) + ); + end component; + +end; diff --git a/bbc_micro.qpf b/bbc_micro.qpf new file mode 100644 index 0000000..52e0fd0 --- /dev/null +++ b/bbc_micro.qpf @@ -0,0 +1,30 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2009 Altera Corporation +# Your use of Altera Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Altera Program License +# Subscription Agreement, Altera MegaCore Function License +# Agreement, or other applicable license agreement, including, +# without limitation, that your use is for the sole purpose of +# programming logic devices manufactured by Altera and sold by +# Altera or its authorized distributors. Please refer to the +# applicable agreement for further details. +# +# -------------------------------------------------------------------------- # +# +# Quartus II +# Version 9.1 Build 222 10/21/2009 SJ Web Edition +# Date created = 20:48:44 July 12, 2011 +# +# -------------------------------------------------------------------------- # + +QUARTUS_VERSION = "9.1" +DATE = "20:48:44 July 12, 2011" + +# Revisions + +PROJECT_REVISION = "bbc_micro_de1" diff --git a/bbc_micro_de1.qsf b/bbc_micro_de1.qsf new file mode 100644 index 0000000..167ed1c --- /dev/null +++ b/bbc_micro_de1.qsf @@ -0,0 +1,503 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2009 Altera Corporation +# Your use of Altera Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Altera Program License +# Subscription Agreement, Altera MegaCore Function License +# Agreement, or other applicable license agreement, including, +# without limitation, that your use is for the sole purpose of +# programming logic devices manufactured by Altera and sold by +# Altera or its authorized distributors. Please refer to the +# applicable agreement for further details. +# +# -------------------------------------------------------------------------- # +# +# Quartus II +# Version 9.1 Build 222 10/21/2009 SJ Web Edition +# Date created = 20:48:44 July 12, 2011 +# +# -------------------------------------------------------------------------- # +# +# Notes: +# +# 1) The default values for assignments are stored in the file: +# bbc_micro_de1_assignment_defaults.qdf +# If this file doesn't exist, see file: +# assignment_defaults.qdf +# +# 2) Altera recommends that you do not modify this file. This +# file is updated automatically by the Quartus II software +# and any changes you make may be lost or overwritten. +# +# -------------------------------------------------------------------------- # + + +set_global_assignment -name FAMILY "Cyclone II" +set_global_assignment -name DEVICE EP2C20F484C7 +set_global_assignment -name TOP_LEVEL_ENTITY bbc_micro_de1 +set_global_assignment -name ORIGINAL_QUARTUS_VERSION 9.1 +set_global_assignment -name PROJECT_CREATION_TIME_DATE "20:48:44 JULY 12, 2011" +set_global_assignment -name LAST_QUARTUS_VERSION 9.1 +set_global_assignment -name USE_GENERATED_PHYSICAL_CONSTRAINTS OFF -section_id eda_blast_fpga +set_global_assignment -name DEVICE_FILTER_PACKAGE FBGA +set_global_assignment -name DEVICE_FILTER_PIN_COUNT 484 +set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 7 +set_global_assignment -name VHDL_FILE vidproc.vhd +set_global_assignment -name VHDL_FILE mc6845.vhd +set_global_assignment -name VHDL_FILE T65/T65_Pack.vhd +set_global_assignment -name VHDL_FILE T65/T65.vhd +set_global_assignment -name VHDL_FILE T65/T65_ALU.vhd +set_global_assignment -name VHDL_FILE T65/T65_MCode.vhd +set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 +set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 +set_location_assignment PIN_A13 -to GPIO_0[0] +set_location_assignment PIN_B13 -to GPIO_0[1] +set_location_assignment PIN_A14 -to GPIO_0[2] +set_location_assignment PIN_B14 -to GPIO_0[3] +set_location_assignment PIN_A15 -to GPIO_0[4] +set_location_assignment PIN_B15 -to GPIO_0[5] +set_location_assignment PIN_A16 -to GPIO_0[6] +set_location_assignment PIN_B16 -to GPIO_0[7] +set_location_assignment PIN_A17 -to GPIO_0[8] +set_location_assignment PIN_B17 -to GPIO_0[9] +set_location_assignment PIN_A18 -to GPIO_0[10] +set_location_assignment PIN_B18 -to GPIO_0[11] +set_location_assignment PIN_A19 -to GPIO_0[12] +set_location_assignment PIN_B19 -to GPIO_0[13] +set_location_assignment PIN_A20 -to GPIO_0[14] +set_location_assignment PIN_B20 -to GPIO_0[15] +set_location_assignment PIN_C21 -to GPIO_0[16] +set_location_assignment PIN_C22 -to GPIO_0[17] +set_location_assignment PIN_D21 -to GPIO_0[18] +set_location_assignment PIN_D22 -to GPIO_0[19] +set_location_assignment PIN_E21 -to GPIO_0[20] +set_location_assignment PIN_E22 -to GPIO_0[21] +set_location_assignment PIN_F21 -to GPIO_0[22] +set_location_assignment PIN_F22 -to GPIO_0[23] +set_location_assignment PIN_G21 -to GPIO_0[24] +set_location_assignment PIN_G22 -to GPIO_0[25] +set_location_assignment PIN_J21 -to GPIO_0[26] +set_location_assignment PIN_J22 -to GPIO_0[27] +set_location_assignment PIN_K21 -to GPIO_0[28] +set_location_assignment PIN_K22 -to GPIO_0[29] +set_location_assignment PIN_J19 -to GPIO_0[30] +set_location_assignment PIN_J20 -to GPIO_0[31] +set_location_assignment PIN_J18 -to GPIO_0[32] +set_location_assignment PIN_K20 -to GPIO_0[33] +set_location_assignment PIN_L19 -to GPIO_0[34] +set_location_assignment PIN_L18 -to GPIO_0[35] +set_location_assignment PIN_H12 -to GPIO_1[0] +set_location_assignment PIN_H13 -to GPIO_1[1] +set_location_assignment PIN_H14 -to GPIO_1[2] +set_location_assignment PIN_G15 -to GPIO_1[3] +set_location_assignment PIN_E14 -to GPIO_1[4] +set_location_assignment PIN_E15 -to GPIO_1[5] +set_location_assignment PIN_F15 -to GPIO_1[6] +set_location_assignment PIN_G16 -to GPIO_1[7] +set_location_assignment PIN_F12 -to GPIO_1[8] +set_location_assignment PIN_F13 -to GPIO_1[9] +set_location_assignment PIN_C14 -to GPIO_1[10] +set_location_assignment PIN_D14 -to GPIO_1[11] +set_location_assignment PIN_D15 -to GPIO_1[12] +set_location_assignment PIN_D16 -to GPIO_1[13] +set_location_assignment PIN_C17 -to GPIO_1[14] +set_location_assignment PIN_C18 -to GPIO_1[15] +set_location_assignment PIN_C19 -to GPIO_1[16] +set_location_assignment PIN_C20 -to GPIO_1[17] +set_location_assignment PIN_D19 -to GPIO_1[18] +set_location_assignment PIN_D20 -to GPIO_1[19] +set_location_assignment PIN_E20 -to GPIO_1[20] +set_location_assignment PIN_F20 -to GPIO_1[21] +set_location_assignment PIN_E19 -to GPIO_1[22] +set_location_assignment PIN_E18 -to GPIO_1[23] +set_location_assignment PIN_G20 -to GPIO_1[24] +set_location_assignment PIN_G18 -to GPIO_1[25] +set_location_assignment PIN_G17 -to GPIO_1[26] +set_location_assignment PIN_H17 -to GPIO_1[27] +set_location_assignment PIN_J15 -to GPIO_1[28] +set_location_assignment PIN_H18 -to GPIO_1[29] +set_location_assignment PIN_N22 -to GPIO_1[30] +set_location_assignment PIN_N21 -to GPIO_1[31] +set_location_assignment PIN_P15 -to GPIO_1[32] +set_location_assignment PIN_N15 -to GPIO_1[33] +set_location_assignment PIN_P17 -to GPIO_1[34] +set_location_assignment PIN_P18 -to GPIO_1[35] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[0] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[1] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[2] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[3] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[4] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[5] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[6] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[7] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[8] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[9] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[10] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[11] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[12] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[13] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[14] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[15] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[16] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[17] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[18] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[19] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[20] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[21] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[22] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[23] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[24] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[25] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[26] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[27] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[28] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[29] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[30] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[31] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[32] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[33] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[34] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_0[35] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[0] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[1] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[2] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[3] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[4] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[5] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[6] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[7] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[8] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[9] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[10] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[11] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[12] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[13] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[14] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[15] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[16] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[17] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[18] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[19] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[20] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[21] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[22] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[23] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[24] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[25] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[26] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[27] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[28] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[29] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[30] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[31] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[32] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[33] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[34] +set_instance_assignment -name IO_STANDARD LVTTL -to GPIO_1[35] +set_location_assignment PIN_L22 -to SW[0] +set_location_assignment PIN_L21 -to SW[1] +set_location_assignment PIN_M22 -to SW[2] +set_location_assignment PIN_V12 -to SW[3] +set_location_assignment PIN_W12 -to SW[4] +set_location_assignment PIN_U12 -to SW[5] +set_location_assignment PIN_U11 -to SW[6] +set_location_assignment PIN_M2 -to SW[7] +set_location_assignment PIN_M1 -to SW[8] +set_location_assignment PIN_L2 -to SW[9] +set_instance_assignment -name IO_STANDARD LVTTL -to SW[0] +set_instance_assignment -name IO_STANDARD LVTTL -to SW[1] +set_instance_assignment -name IO_STANDARD LVTTL -to SW[2] +set_instance_assignment -name IO_STANDARD LVTTL -to SW[3] +set_instance_assignment -name IO_STANDARD LVTTL -to SW[4] +set_instance_assignment -name IO_STANDARD LVTTL -to SW[5] +set_instance_assignment -name IO_STANDARD LVTTL -to SW[6] +set_instance_assignment -name IO_STANDARD LVTTL -to SW[7] +set_instance_assignment -name IO_STANDARD LVTTL -to SW[8] +set_instance_assignment -name IO_STANDARD LVTTL -to SW[9] +set_location_assignment PIN_J2 -to HEX0[0] +set_location_assignment PIN_J1 -to HEX0[1] +set_location_assignment PIN_H2 -to HEX0[2] +set_location_assignment PIN_H1 -to HEX0[3] +set_location_assignment PIN_F2 -to HEX0[4] +set_location_assignment PIN_F1 -to HEX0[5] +set_location_assignment PIN_E2 -to HEX0[6] +set_location_assignment PIN_E1 -to HEX1[0] +set_location_assignment PIN_H6 -to HEX1[1] +set_location_assignment PIN_H5 -to HEX1[2] +set_location_assignment PIN_H4 -to HEX1[3] +set_location_assignment PIN_G3 -to HEX1[4] +set_location_assignment PIN_D2 -to HEX1[5] +set_location_assignment PIN_D1 -to HEX1[6] +set_location_assignment PIN_G5 -to HEX2[0] +set_location_assignment PIN_G6 -to HEX2[1] +set_location_assignment PIN_C2 -to HEX2[2] +set_location_assignment PIN_C1 -to HEX2[3] +set_location_assignment PIN_E3 -to HEX2[4] +set_location_assignment PIN_E4 -to HEX2[5] +set_location_assignment PIN_D3 -to HEX2[6] +set_location_assignment PIN_F4 -to HEX3[0] +set_location_assignment PIN_D5 -to HEX3[1] +set_location_assignment PIN_D6 -to HEX3[2] +set_location_assignment PIN_J4 -to HEX3[3] +set_location_assignment PIN_L8 -to HEX3[4] +set_location_assignment PIN_F3 -to HEX3[5] +set_location_assignment PIN_D4 -to HEX3[6] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX0[0] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX0[1] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX0[2] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX0[3] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX0[4] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX0[5] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX0[6] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX1[0] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX1[1] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX1[2] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX1[3] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX1[4] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX1[5] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX1[6] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX2[0] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX2[1] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX2[2] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX2[3] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX2[4] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX2[5] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX2[6] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX3[0] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX3[1] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX3[2] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX3[3] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX3[4] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX3[5] +set_instance_assignment -name IO_STANDARD LVTTL -to HEX3[6] +set_location_assignment PIN_R22 -to KEY[0] +set_location_assignment PIN_R21 -to KEY[1] +set_location_assignment PIN_T22 -to KEY[2] +set_location_assignment PIN_T21 -to KEY[3] +set_location_assignment PIN_R20 -to LEDR[0] +set_location_assignment PIN_R19 -to LEDR[1] +set_location_assignment PIN_U19 -to LEDR[2] +set_location_assignment PIN_Y19 -to LEDR[3] +set_location_assignment PIN_T18 -to LEDR[4] +set_location_assignment PIN_V19 -to LEDR[5] +set_location_assignment PIN_Y18 -to LEDR[6] +set_location_assignment PIN_U18 -to LEDR[7] +set_location_assignment PIN_R18 -to LEDR[8] +set_location_assignment PIN_R17 -to LEDR[9] +set_location_assignment PIN_U22 -to LEDG[0] +set_location_assignment PIN_U21 -to LEDG[1] +set_location_assignment PIN_V22 -to LEDG[2] +set_location_assignment PIN_V21 -to LEDG[3] +set_location_assignment PIN_W22 -to LEDG[4] +set_location_assignment PIN_W21 -to LEDG[5] +set_location_assignment PIN_Y22 -to LEDG[6] +set_location_assignment PIN_Y21 -to LEDG[7] +set_instance_assignment -name IO_STANDARD LVTTL -to KEY[0] +set_instance_assignment -name IO_STANDARD LVTTL -to KEY[1] +set_instance_assignment -name IO_STANDARD LVTTL -to KEY[2] +set_instance_assignment -name IO_STANDARD LVTTL -to KEY[3] +set_instance_assignment -name IO_STANDARD LVTTL -to LEDR[0] +set_instance_assignment -name IO_STANDARD LVTTL -to LEDR[1] +set_instance_assignment -name IO_STANDARD LVTTL -to LEDR[2] +set_instance_assignment -name IO_STANDARD LVTTL -to LEDR[3] +set_instance_assignment -name IO_STANDARD LVTTL -to LEDR[4] +set_instance_assignment -name IO_STANDARD LVTTL -to LEDR[5] +set_instance_assignment -name IO_STANDARD LVTTL -to LEDR[6] +set_instance_assignment -name IO_STANDARD LVTTL -to LEDR[7] +set_instance_assignment -name IO_STANDARD LVTTL -to LEDR[8] +set_instance_assignment -name IO_STANDARD LVTTL -to LEDR[9] +set_instance_assignment -name IO_STANDARD LVTTL -to LEDG[0] +set_instance_assignment -name IO_STANDARD LVTTL -to LEDG[1] +set_instance_assignment -name IO_STANDARD LVTTL -to LEDG[2] +set_instance_assignment -name IO_STANDARD LVTTL -to LEDG[3] +set_instance_assignment -name IO_STANDARD LVTTL -to LEDG[4] +set_instance_assignment -name IO_STANDARD LVTTL -to LEDG[5] +set_instance_assignment -name IO_STANDARD LVTTL -to LEDG[6] +set_instance_assignment -name IO_STANDARD LVTTL -to LEDG[7] +set_location_assignment PIN_D12 -to CLOCK_27[0] +set_location_assignment PIN_E12 -to CLOCK_27[1] +set_location_assignment PIN_B12 -to CLOCK_24[0] +set_location_assignment PIN_A12 -to CLOCK_24[1] +set_location_assignment PIN_L1 -to CLOCK_50 +set_location_assignment PIN_M21 -to EXT_CLOCK +set_instance_assignment -name IO_STANDARD LVTTL -to CLOCK_27[1] +set_instance_assignment -name IO_STANDARD LVTTL -to CLOCK_24[0] +set_instance_assignment -name IO_STANDARD LVTTL -to CLOCK_24[1] +set_instance_assignment -name IO_STANDARD LVTTL -to CLOCK_50 +set_instance_assignment -name IO_STANDARD LVTTL -to EXT_CLOCK +set_location_assignment PIN_H15 -to PS2_CLK +set_location_assignment PIN_J14 -to PS2_DAT +set_location_assignment PIN_F14 -to UART_RXD +set_location_assignment PIN_G12 -to UART_TXD +set_instance_assignment -name IO_STANDARD LVTTL -to PS2_CLK +set_instance_assignment -name IO_STANDARD LVTTL -to PS2_DAT +set_instance_assignment -name IO_STANDARD LVTTL -to UART_RXD +set_instance_assignment -name IO_STANDARD LVTTL -to UART_TXD +set_location_assignment PIN_E8 -to TDI +set_location_assignment PIN_D8 -to TCS +set_location_assignment PIN_C7 -to TCK +set_location_assignment PIN_D7 -to TDO +set_instance_assignment -name IO_STANDARD LVTTL -to TDI +set_instance_assignment -name IO_STANDARD LVTTL -to TCS +set_instance_assignment -name IO_STANDARD LVTTL -to TCK +set_instance_assignment -name IO_STANDARD LVTTL -to TDO +set_location_assignment PIN_D9 -to VGA_R[0] +set_location_assignment PIN_C9 -to VGA_R[1] +set_location_assignment PIN_A7 -to VGA_R[2] +set_location_assignment PIN_B7 -to VGA_R[3] +set_location_assignment PIN_B8 -to VGA_G[0] +set_location_assignment PIN_C10 -to VGA_G[1] +set_location_assignment PIN_B9 -to VGA_G[2] +set_location_assignment PIN_A8 -to VGA_G[3] +set_location_assignment PIN_A9 -to VGA_B[0] +set_location_assignment PIN_D11 -to VGA_B[1] +set_location_assignment PIN_A10 -to VGA_B[2] +set_location_assignment PIN_B10 -to VGA_B[3] +set_location_assignment PIN_A11 -to VGA_HS +set_location_assignment PIN_B11 -to VGA_VS +set_instance_assignment -name IO_STANDARD LVTTL -to VGA_R[0] +set_instance_assignment -name IO_STANDARD LVTTL -to VGA_R[1] +set_instance_assignment -name IO_STANDARD LVTTL -to VGA_R[2] +set_instance_assignment -name IO_STANDARD LVTTL -to VGA_R[3] +set_instance_assignment -name IO_STANDARD LVTTL -to VGA_G[0] +set_instance_assignment -name IO_STANDARD LVTTL -to VGA_G[1] +set_instance_assignment -name IO_STANDARD LVTTL -to VGA_G[2] +set_instance_assignment -name IO_STANDARD LVTTL -to VGA_G[3] +set_instance_assignment -name IO_STANDARD LVTTL -to VGA_B[0] +set_instance_assignment -name IO_STANDARD LVTTL -to VGA_B[1] +set_instance_assignment -name IO_STANDARD LVTTL -to VGA_B[2] +set_instance_assignment -name IO_STANDARD LVTTL -to VGA_B[3] +set_instance_assignment -name IO_STANDARD LVTTL -to VGA_HS +set_instance_assignment -name IO_STANDARD LVTTL -to VGA_VS +set_location_assignment PIN_A3 -to I2C_SCLK +set_location_assignment PIN_B3 -to I2C_SDAT +set_location_assignment PIN_A6 -to AUD_ADCLRCK +set_location_assignment PIN_B6 -to AUD_ADCDAT +set_location_assignment PIN_A5 -to AUD_DACLRCK +set_location_assignment PIN_B5 -to AUD_DACDAT +set_location_assignment PIN_B4 -to AUD_XCK +set_location_assignment PIN_A4 -to AUD_BCLK +set_instance_assignment -name IO_STANDARD LVTTL -to I2C_SCLK +set_instance_assignment -name IO_STANDARD LVTTL -to I2C_SDAT +set_instance_assignment -name IO_STANDARD LVTTL -to AUD_ADCLRCK +set_instance_assignment -name IO_STANDARD LVTTL -to AUD_ADCDAT +set_instance_assignment -name IO_STANDARD LVTTL -to AUD_DACLRCK +set_instance_assignment -name IO_STANDARD LVTTL -to AUD_DACDAT +set_instance_assignment -name IO_STANDARD LVTTL -to AUD_XCK +set_instance_assignment -name IO_STANDARD LVTTL -to AUD_BCLK +set_location_assignment PIN_W4 -to DRAM_ADDR[0] +set_location_assignment PIN_W5 -to DRAM_ADDR[1] +set_location_assignment PIN_Y3 -to DRAM_ADDR[2] +set_location_assignment PIN_Y4 -to DRAM_ADDR[3] +set_location_assignment PIN_R6 -to DRAM_ADDR[4] +set_location_assignment PIN_R5 -to DRAM_ADDR[5] +set_location_assignment PIN_P6 -to DRAM_ADDR[6] +set_location_assignment PIN_P5 -to DRAM_ADDR[7] +set_location_assignment PIN_P3 -to DRAM_ADDR[8] +set_location_assignment PIN_N4 -to DRAM_ADDR[9] +set_location_assignment PIN_W3 -to DRAM_ADDR[10] +set_location_assignment PIN_N6 -to DRAM_ADDR[11] +set_location_assignment PIN_U3 -to DRAM_BA_0 +set_location_assignment PIN_V4 -to DRAM_BA_1 +set_location_assignment PIN_T3 -to DRAM_CAS_N +set_location_assignment PIN_N3 -to DRAM_CKE +set_location_assignment PIN_U4 -to DRAM_CLK +set_location_assignment PIN_T6 -to DRAM_CS_N +set_location_assignment PIN_U1 -to DRAM_DQ[0] +set_location_assignment PIN_U2 -to DRAM_DQ[1] +set_location_assignment PIN_V1 -to DRAM_DQ[2] +set_location_assignment PIN_V2 -to DRAM_DQ[3] +set_location_assignment PIN_W1 -to DRAM_DQ[4] +set_location_assignment PIN_W2 -to DRAM_DQ[5] +set_location_assignment PIN_Y1 -to DRAM_DQ[6] +set_location_assignment PIN_Y2 -to DRAM_DQ[7] +set_location_assignment PIN_N1 -to DRAM_DQ[8] +set_location_assignment PIN_N2 -to DRAM_DQ[9] +set_location_assignment PIN_P1 -to DRAM_DQ[10] +set_location_assignment PIN_P2 -to DRAM_DQ[11] +set_location_assignment PIN_R1 -to DRAM_DQ[12] +set_location_assignment PIN_R2 -to DRAM_DQ[13] +set_location_assignment PIN_T1 -to DRAM_DQ[14] +set_location_assignment PIN_T2 -to DRAM_DQ[15] +set_location_assignment PIN_R7 -to DRAM_LDQM +set_location_assignment PIN_T5 -to DRAM_RAS_N +set_location_assignment PIN_M5 -to DRAM_UDQM +set_location_assignment PIN_R8 -to DRAM_WE_N +set_location_assignment PIN_AB20 -to FL_ADDR[0] +set_location_assignment PIN_AA14 -to FL_ADDR[1] +set_location_assignment PIN_Y16 -to FL_ADDR[2] +set_location_assignment PIN_R15 -to FL_ADDR[3] +set_location_assignment PIN_T15 -to FL_ADDR[4] +set_location_assignment PIN_U15 -to FL_ADDR[5] +set_location_assignment PIN_V15 -to FL_ADDR[6] +set_location_assignment PIN_W15 -to FL_ADDR[7] +set_location_assignment PIN_R14 -to FL_ADDR[8] +set_location_assignment PIN_Y13 -to FL_ADDR[9] +set_location_assignment PIN_R12 -to FL_ADDR[10] +set_location_assignment PIN_T12 -to FL_ADDR[11] +set_location_assignment PIN_AB14 -to FL_ADDR[12] +set_location_assignment PIN_AA13 -to FL_ADDR[13] +set_location_assignment PIN_AB13 -to FL_ADDR[14] +set_location_assignment PIN_AA12 -to FL_ADDR[15] +set_location_assignment PIN_AB12 -to FL_ADDR[16] +set_location_assignment PIN_AA20 -to FL_ADDR[17] +set_location_assignment PIN_U14 -to FL_ADDR[18] +set_location_assignment PIN_V14 -to FL_ADDR[19] +set_location_assignment PIN_U13 -to FL_ADDR[20] +set_location_assignment PIN_R13 -to FL_ADDR[21] +set_location_assignment PIN_AB16 -to FL_DQ[0] +set_location_assignment PIN_AA16 -to FL_DQ[1] +set_location_assignment PIN_AB17 -to FL_DQ[2] +set_location_assignment PIN_AA17 -to FL_DQ[3] +set_location_assignment PIN_AB18 -to FL_DQ[4] +set_location_assignment PIN_AA18 -to FL_DQ[5] +set_location_assignment PIN_AB19 -to FL_DQ[6] +set_location_assignment PIN_AA19 -to FL_DQ[7] +set_location_assignment PIN_AA15 -to FL_OE_N +set_location_assignment PIN_W14 -to FL_RST_N +set_location_assignment PIN_Y14 -to FL_WE_N +set_location_assignment PIN_AA3 -to SRAM_ADDR[0] +set_location_assignment PIN_AB3 -to SRAM_ADDR[1] +set_location_assignment PIN_AA4 -to SRAM_ADDR[2] +set_location_assignment PIN_AB4 -to SRAM_ADDR[3] +set_location_assignment PIN_AA5 -to SRAM_ADDR[4] +set_location_assignment PIN_AB10 -to SRAM_ADDR[5] +set_location_assignment PIN_AA11 -to SRAM_ADDR[6] +set_location_assignment PIN_AB11 -to SRAM_ADDR[7] +set_location_assignment PIN_V11 -to SRAM_ADDR[8] +set_location_assignment PIN_W11 -to SRAM_ADDR[9] +set_location_assignment PIN_R11 -to SRAM_ADDR[10] +set_location_assignment PIN_T11 -to SRAM_ADDR[11] +set_location_assignment PIN_Y10 -to SRAM_ADDR[12] +set_location_assignment PIN_U10 -to SRAM_ADDR[13] +set_location_assignment PIN_R10 -to SRAM_ADDR[14] +set_location_assignment PIN_T7 -to SRAM_ADDR[15] +set_location_assignment PIN_Y6 -to SRAM_ADDR[16] +set_location_assignment PIN_Y5 -to SRAM_ADDR[17] +set_location_assignment PIN_AB5 -to SRAM_CE_N +set_location_assignment PIN_AA6 -to SRAM_DQ[0] +set_location_assignment PIN_AB6 -to SRAM_DQ[1] +set_location_assignment PIN_AA7 -to SRAM_DQ[2] +set_location_assignment PIN_AB7 -to SRAM_DQ[3] +set_location_assignment PIN_AA8 -to SRAM_DQ[4] +set_location_assignment PIN_AB8 -to SRAM_DQ[5] +set_location_assignment PIN_AA9 -to SRAM_DQ[6] +set_location_assignment PIN_AB9 -to SRAM_DQ[7] +set_location_assignment PIN_Y9 -to SRAM_DQ[8] +set_location_assignment PIN_W9 -to SRAM_DQ[9] +set_location_assignment PIN_V9 -to SRAM_DQ[10] +set_location_assignment PIN_U9 -to SRAM_DQ[11] +set_location_assignment PIN_R9 -to SRAM_DQ[12] +set_location_assignment PIN_W8 -to SRAM_DQ[13] +set_location_assignment PIN_V8 -to SRAM_DQ[14] +set_location_assignment PIN_U8 -to SRAM_DQ[15] +set_location_assignment PIN_Y7 -to SRAM_LB_N +set_location_assignment PIN_T8 -to SRAM_OE_N +set_location_assignment PIN_W7 -to SRAM_UB_N +set_location_assignment PIN_AA10 -to SRAM_WE_N +set_global_assignment -name USE_CONFIGURATION_DEVICE ON +set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED WITH WEAK PULL-UP" \ No newline at end of file diff --git a/mc6845.vhd b/mc6845.vhd new file mode 100644 index 0000000..d2098c4 --- /dev/null +++ b/mc6845.vhd @@ -0,0 +1,419 @@ +-- MC6845 CRTC +-- +-- Synchronous implementation for FPGA +-- +-- (C) 2011 Mike Stirling +-- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +entity mc6845 is +port ( + CLOCK : in std_logic; + CLKEN : in std_logic; + nRESET : in std_logic; + + -- Bus interface + ENABLE : in std_logic; + R_nW : in std_logic; + RS : in std_logic; + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0); + + -- Display interface + VSYNC : out std_logic; + HSYNC : out std_logic; + DE : out std_logic; + CURSOR : out std_logic; + LPSTB : in std_logic; + + -- Memory interface + MA : out std_logic_vector(13 downto 0); + RA : out std_logic_vector(4 downto 0) + ); +end entity; + +architecture rtl of mc6845 is + +-- Host-accessible registers +signal addr_reg : std_logic_vector(4 downto 0); -- Currently addressed register +-- These are write-only +signal r00_h_total : unsigned(7 downto 0); -- Horizontal total, chars +signal r01_h_displayed : unsigned(7 downto 0); -- Horizontal active, chars +signal r02_h_sync_pos : unsigned(7 downto 0); -- Horizontal sync position, chars +signal r03_v_sync_width : unsigned(3 downto 0); -- Vertical sync width, scan lines (0=16 lines) +signal r03_h_sync_width : unsigned(3 downto 0); -- Horizontal sync width, chars (0=no sync) +signal r04_v_total : unsigned(6 downto 0); -- Vertical total, character rows +signal r05_v_total_adj : unsigned(4 downto 0); -- Vertical offset, scan lines +signal r06_v_displayed : unsigned(6 downto 0); -- Vertical active, character rows +signal r07_v_sync_pos : unsigned(6 downto 0); -- Vertical sync position, character rows +signal r08_interlace : std_logic_vector(1 downto 0); +signal r09_max_scan_line_addr : unsigned(4 downto 0); +signal r10_cursor_mode : std_logic_vector(1 downto 0); +signal r10_cursor_start : unsigned(4 downto 0); -- Cursor start, scan lines +signal r11_cursor_end : unsigned(4 downto 0); -- Cursor end, scan lines +signal r12_start_addr_h : unsigned(5 downto 0); +signal r13_start_addr_l : unsigned(7 downto 0); +-- These are read/write +signal r14_cursor_h : unsigned(5 downto 0); +signal r15_cursor_l : unsigned(7 downto 0); +-- These are read-only +signal r16_light_pen_h : unsigned(5 downto 0); +signal r17_light_pen_l : unsigned(7 downto 0); + + +-- Timing generation +-- Horizontal counter counts position on line +signal h_counter : unsigned(7 downto 0); +-- HSYNC counter counts duration of sync pulse +signal h_sync_counter : unsigned(3 downto 0); +-- Row counter counts current character row +signal row_counter : unsigned(6 downto 0); +-- Line counter counts current line within each character row +signal line_counter : unsigned(4 downto 0); +-- VSYNC counter counts duration of sync pulse +signal v_sync_counter : unsigned(3 downto 0); +-- Field counter counts number of complete fields for cursor flash +signal field_counter : unsigned(5 downto 0); + +-- Internal signals +signal h_sync_start : std_logic; +signal h_half_way : std_logic; +signal h_display : std_logic; +signal hs : std_logic; +signal v_display : std_logic; +signal vs : std_logic; +signal odd_field : std_logic; +signal ma_i : unsigned(13 downto 0); +signal ma_row_start : unsigned(13 downto 0); -- Start address of current character row +signal cursor_i : std_logic; +signal lpstb_i : std_logic; + + +begin + HSYNC <= hs; -- External HSYNC driven directly from internal signal + VSYNC <= vs; -- External VSYNC driven directly from internal signal + DE <= h_display and v_display; + + -- Cursor output generated combinatorially from the internal signal in + -- accordance with the currently selected cursor mode + CURSOR <= cursor_i when r10_cursor_mode = "00" else + '0' when r10_cursor_mode = "01" else + (cursor_i and field_counter(4)) when r10_cursor_mode = "10" else + (cursor_i and field_counter(5)); + + -- Synchronous register access. Enabled on every clock. + process(CLOCK,nRESET) + begin + if nRESET = '0' then + -- Reset registers to defaults + addr_reg <= (others => '0'); + r00_h_total <= (others => '0'); + r01_h_displayed <= (others => '0'); + r02_h_sync_pos <= (others => '0'); + r03_v_sync_width <= (others => '0'); + r03_h_sync_width <= (others => '0'); + r04_v_total <= (others => '0'); + r05_v_total_adj <= (others => '0'); + r06_v_displayed <= (others => '0'); + r07_v_sync_pos <= (others => '0'); + r08_interlace <= (others => '0'); + r09_max_scan_line_addr <= (others => '0'); + r10_cursor_mode <= (others => '0'); + r10_cursor_start <= (others => '0'); + r11_cursor_end <= (others => '0'); + r12_start_addr_h <= (others => '0'); + r13_start_addr_l <= (others => '0'); + r14_cursor_h <= (others => '0'); + r15_cursor_l <= (others => '0'); + + DO <= (others => '0'); + elsif rising_edge(CLOCK) then + if ENABLE = '1' then + if R_nW = '1' then + -- Read + case addr_reg is + when "01110" => + DO <= "00" & std_logic_vector(r14_cursor_h); + when "01111" => + DO <= std_logic_vector(r15_cursor_l); + when "10000" => + DO <= "00" & std_logic_vector(r16_light_pen_h); + when "10001" => + DO <= std_logic_vector(r17_light_pen_l); + when others => + DO <= (others => '0'); + end case; + else + -- Write + if RS = '0' then + addr_reg <= DI(4 downto 0); + else + case addr_reg is + when "00000" => + r00_h_total <= unsigned(DI); + when "00001" => + r01_h_displayed <= unsigned(DI); + when "00010" => + r02_h_sync_pos <= unsigned(DI); + when "00011" => + r03_v_sync_width <= unsigned(DI(7 downto 4)); + r03_h_sync_width <= unsigned(DI(3 downto 0)); + when "00100" => + r04_v_total <= unsigned(DI(6 downto 0)); + when "00101" => + r05_v_total_adj <= unsigned(DI(4 downto 0)); + when "00110" => + r06_v_displayed <= unsigned(DI(6 downto 0)); + when "00111" => + r07_v_sync_pos <= unsigned(DI(6 downto 0)); + when "01000" => + r08_interlace <= DI(1 downto 0); + when "01001" => + r09_max_scan_line_addr <= unsigned(DI(4 downto 0)); + when "01010" => + r10_cursor_mode <= DI(6 downto 5); + r10_cursor_start <= unsigned(DI(4 downto 0)); + when "01011" => + r11_cursor_end <= unsigned(DI(4 downto 0)); + when "01100" => + r12_start_addr_h <= unsigned(DI(5 downto 0)); + when "01101" => + r13_start_addr_l <= unsigned(DI(7 downto 0)); + when "01110" => + r14_cursor_h <= unsigned(DI(5 downto 0)); + when "01111" => + r15_cursor_l <= unsigned(DI(7 downto 0)); + when others => + null; + end case; + end if; + end if; + end if; + end if; + end process; -- registers + + -- Horizontal, vertical and address counters + process(CLOCK,nRESET) + variable ma_row_start : unsigned(13 downto 0); + begin + if nRESET = '0' then + -- H + h_counter <= (others => '0'); + + -- V + line_counter <= (others => '0'); + row_counter <= (others => '0'); + odd_field <= '0'; + + -- Fields (cursor flash) + field_counter <= (others => '0'); + + -- Addressing + ma_row_start := (others => '0'); + ma_i <= (others => '0'); + elsif rising_edge(CLOCK) and CLKEN='1' then + -- Horizontal counter increments on each clock, wrapping at + -- h_total + if h_counter = r00_h_total then + -- h_total reached + h_counter <= (others => '0'); + + -- Scan line counter increments, wrapping at max_scan_line_addr + if line_counter = r09_max_scan_line_addr then + -- Next character row + -- FIXME: No support for v_total_adj yet + line_counter <= (others => '0'); + if row_counter = r04_v_total then + -- If in interlace mode we toggle to the opposite field. + -- Save on some logic by doing this here rather than at the + -- end of v_total_adj - it shouldn't make any difference to the + -- output + if r08_interlace(0) = '1' then + odd_field <= not odd_field; + else + odd_field <= '0'; + end if; + + -- Address is loaded from start address register at the top of + -- each field and the row counter is reset + ma_row_start := r12_start_addr_h & r13_start_addr_l; + row_counter <= (others => '0'); + + -- Increment field counter + field_counter <= field_counter + 1; + else + -- On all other chracter rows within the field the row start address is + -- increased by h_displayed and the row counter is incremented + ma_row_start := ma_row_start + r01_h_displayed; + row_counter <= row_counter + 1; + end if; + else + -- Next scan line + line_counter <= line_counter + 1; + end if; + + -- Memory address preset to row start at the beginning of each + -- scan line + ma_i <= ma_row_start; + else + -- Increment horizontal counter + h_counter <= h_counter + 1; + -- Increment memory address + ma_i <= ma_i + 1; + end if; + end if; + end process; + + -- Signals to mark hsync and half way points for generating + -- vsync in even and odd fields + process(h_counter) + begin + h_sync_start <= '0'; + h_half_way <= '0'; + + if h_counter = r02_h_sync_pos then + h_sync_start <= '1'; + end if; + if h_counter = "0" & r02_h_sync_pos(7 downto 1) then + h_half_way <= '1'; + end if; + end process; + + -- Video timing and sync counters + process(CLOCK,nRESET) + begin + if nRESET = '0' then + -- H + h_display <= '0'; + hs <= '0'; + h_sync_counter <= (others => '0'); + + -- V + v_display <= '0'; + vs <= '0'; + v_sync_counter <= (others => '0'); + elsif rising_edge(CLOCK) and CLKEN = '1' then + -- Horizontal active video + if h_counter = 0 then + -- Start of active video + h_display <= '1'; + end if; + if h_counter = r01_h_displayed then + -- End of active video + h_display <= '0'; + end if; + + -- Horizontal sync + if h_sync_start = '1' or hs = '1' then + -- In horizontal sync + hs <= '1'; + h_sync_counter <= h_sync_counter + 1; + else + h_sync_counter <= (others => '0'); + end if; + if h_sync_counter = r03_h_sync_width then + -- Terminate hsync after h_sync_width (0 means no hsync so this + -- can immediately override the setting above) + hs <= '0'; + end if; + + -- Vertical active video + if row_counter = 0 then + -- Start of active video + v_display <= '1'; + end if; + if row_counter = r06_v_displayed then + -- End of active video + v_display <= '0'; + end if; + + -- Vertical sync occurs either at the same time as the horizontal sync (even fields) + -- or half a line later (odd fields) + if (odd_field = '0' and h_sync_start = '1') or (odd_field = '1' and h_half_way = '1') then + if (row_counter = r07_v_sync_pos and line_counter = 0) or vs = '1' then + -- In vertical sync + vs <= '1'; + v_sync_counter <= v_sync_counter + 1; + else + v_sync_counter <= (others => '0'); + end if; + if v_sync_counter = r03_v_sync_width and vs = '1' then + -- Terminate vsync after v_sync_width (0 means 16 lines so this is + -- masked by 'vs' to ensure a full turn of the counter in this case) + vs <= '0'; + end if; + end if; + end if; + end process; + + -- Address generation + process(CLOCK,nRESET) + begin + if nRESET = '0' then + RA <= (others => '0'); + MA <= (others => '0'); + elsif rising_edge(CLOCK) and CLKEN = '1' then + -- Character row address is just the scan line counter delayed by + -- one clock to line up with the syncs. + -- FIXME: Interlace sync + video mode needs special row addressing + RA <= std_logic_vector(line_counter); + -- Internal memory address delayed by one cycle as well + MA <= std_logic_vector(ma_i); + end if; + end process; + + -- Cursor control + process(CLOCK,nRESET) + variable cursor_line : std_logic; + begin + -- Internal cursor enable signal delayed by 1 clock to line up + -- with address outputs + if nRESET = '0' then + cursor_i <= '0'; + cursor_line := '0'; + elsif rising_edge(CLOCK) and CLKEN = '1' then + if ma_i = r14_cursor_h & r15_cursor_l then + if line_counter = r10_cursor_start then + -- First cursor scanline + cursor_line := '1'; + end if; + + -- Cursor output is asserted within the current cursor character + -- on the selected lines only + cursor_i <= cursor_line; + + if line_counter = r11_cursor_end then + -- Last cursor scanline + cursor_line := '0'; + end if; + else + -- Cursor is off in all character positions apart from the + -- selected one + cursor_i <= '0'; + end if; + end if; + end process; + + -- Light pen capture + process(CLOCK,nRESET) + begin + if nRESET = '0' then + lpstb_i <= '0'; + r16_light_pen_h <= (others => '0'); + r17_light_pen_l <= (others => '0'); + elsif rising_edge(CLOCK) and CLKEN = '1' then + -- Register light-pen strobe input + lpstb_i <= LPSTB; + + if LPSTB = '1' and lpstb_i = '0' then + -- Capture address on rising edge + r16_light_pen_h <= ma_i(13 downto 8); + r17_light_pen_l <= ma_i(7 downto 0); + end if; + end if; + end process; +end architecture; + + diff --git a/vidproc.vhd b/vidproc.vhd new file mode 100644 index 0000000..485cd15 --- /dev/null +++ b/vidproc.vhd @@ -0,0 +1,192 @@ +-- BBC Micro "VIDPROC" Video ULA +-- +-- Synchronous implementation for FPGA +-- +-- (C) 2011 Mike Stirling +-- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +entity vidproc is +port ( + CLOCK : in std_logic; + -- Clock enable qualifies display cycles (interleaved with CPU cycles) + CLKEN : in std_logic; + nRESET : in std_logic; + + -- Clock enable output to CRTC + CLKEN_CRTC : out std_logic; + + -- Bus interface + ENABLE : in std_logic; + A0 : in std_logic; + -- CPU data bus (for register writes) + DI_CPU : in std_logic_vector(7 downto 0); + -- Display RAM data bus (for display data fetch) + DI_RAM : in std_logic_vector(7 downto 0); + + -- Control interface + nINVERT : in std_logic; + DISEN : in std_logic; + CURSOR : in std_logic; + + -- Video in (teletext mode) + R_IN : in std_logic; + G_IN : in std_logic; + B_IN : in std_logic; + + -- Video out + R : out std_logic; + G : out std_logic; + B : out std_logic + ); +end entity; + +architecture rtl of vidproc is +-- Write-only registers +signal r0_cursor0 : std_logic; +signal r0_cursor1 : std_logic; +signal r0_cursor2 : std_logic; +signal r0_crtc_2mhz : std_logic; +signal r0_pixel_rate : std_logic_vector(1 downto 0); +signal r0_teletext : std_logic; +signal r0_flash : std_logic; + +type palette_t is array(0 to 15) of std_logic_vector(3 downto 0); +signal palette : palette_t; + +-- Pixel shift register +signal shiftreg : std_logic_vector(7 downto 0); +-- Delayed display enable +signal delayed_disen : std_logic; + +-- Internal clock enable generation +signal clken_pixel : std_logic; +signal clken_counter : unsigned(3 downto 0); + +begin + -- Synchronous register access, enabled on every clock + process(CLOCK,nRESET) + begin + if nRESET = '0' then + r0_cursor0 <= '0'; + r0_cursor1 <= '0'; + r0_cursor2 <= '0'; + r0_crtc_2mhz <= '0'; + r0_pixel_rate <= "00"; + r0_teletext <= '0'; + r0_flash <= '0'; + + for colour in 0 to 15 loop + palette(colour) <= (others => '0'); + end loop; + elsif rising_edge(CLOCK) then + if ENABLE = '1' then + if A0 = '0' then + -- Access control register + r0_cursor0 <= DI_CPU(7); + r0_cursor1 <= DI_CPU(6); + r0_cursor2 <= DI_CPU(5); + r0_crtc_2mhz <= DI_CPU(4); + r0_pixel_rate <= DI_CPU(3 downto 2); + r0_teletext <= DI_CPU(1); + r0_flash <= DI_CPU(0); + else + -- Access palette register + palette(to_integer(unsigned(DI_CPU(7 downto 4)))) <= DI_CPU(3 downto 0); + end if; + end if; + end if; + end process; + + -- Clock enable generation. + -- Pixel clock can be divided by 1,2,4 or 8 depending on the value + -- programmed at r0_pixel_rate + -- 00 = /8, 01 = /4, 10 = /2, 11 = /1 + clken_pixel <= + CLKEN when r0_pixel_rate = "11" else + (CLKEN and not clken_counter(0)) when r0_pixel_rate = "10" else + (CLKEN and not (clken_counter(0) or clken_counter(1))) when r0_pixel_rate = "01" else + (CLKEN and not (clken_counter(0) or clken_counter(1) or clken_counter(2))); + + -- The CRT controller is always enabled in the 15th cycle, so that the result + -- is ready for latching into the shift register in cycle 0. If 2 MHz mode is + -- selected then the CRTC is also enabled in the 7th cycle + CLKEN_CRTC <= CLKEN and + clken_counter(0) and clken_counter(1) and clken_counter(2) and + (clken_counter(3) or r0_crtc_2mhz); + + process(CLOCK,nRESET) + begin + if nRESET = '0' then + clken_counter <= (others => '0'); + elsif rising_edge(CLOCK) and CLKEN = '1' then + -- Increment internal cycle counter during each video clock + clken_counter <= clken_counter + 1; + end if; + end process; + + -- Fetch control + process(CLOCK,nRESET) + begin + if nRESET = '0' then + shiftreg <= (others => '0'); + elsif rising_edge(CLOCK) and clken_pixel = '1' then + if clken_counter = "0000" or + (clken_counter = "1000" and r0_crtc_2mhz = '1') then + -- Fetch next byte from RAM into shift register. This always occurs in + -- cycle 0, and also in cycle 8 if the CRTC is clocked at double rate. + shiftreg <= DI_RAM; + else + -- Clock shift register and input '1' at LSB + shiftreg <= shiftreg(6 downto 0) & "1"; + end if; + end if; + end process; + + -- Pixel generation + -- The new shift register contents are loaded during + -- cycle 0 (and 8) but will not be read here until the next cycle. + -- By running this process on every single video tick instead of at + -- the pixel rate we ensure that the resulting delay is minimal and + -- constant (running this at the pixel rate would cause + -- the display to move slightly depending on which mode was selected). + process(CLOCK,nRESET) + variable palette_a : std_logic_vector(3 downto 0); + variable dot_val : std_logic_vector(3 downto 0); + variable red_val : std_logic; + variable green_val : std_logic; + variable blue_val : std_logic; + begin + if nRESET = '0' then + R <= '0'; + G <= '0'; + B <= '0'; + delayed_disen <= '0'; + elsif rising_edge(CLOCK) and CLKEN = '1' then + -- Look up dot value in the palette. Bits are as follows: + -- bit 3 - FLASH + -- bit 2 - Not BLUE + -- bit 1 - Not GREEN + -- bit 0 - Not RED + palette_a := shiftreg(7) & shiftreg(5) & shiftreg(3) & shiftreg(1); + dot_val := palette(to_integer(unsigned(palette_a))); + + -- Apply flash inversion if required + red_val := (dot_val(3) and r0_flash) xor not dot_val(0); + green_val := (dot_val(3) and r0_flash) xor not dot_val(1); + blue_val := (dot_val(3) and r0_flash) xor not dot_val(2); + + -- To output + -- FIXME: Cursor and INVERT option, teletext + R <= red_val and delayed_disen; + G <= green_val and delayed_disen; + B <= blue_val and delayed_disen; + + -- Display enable signal delayed by one clock + delayed_disen <= DISEN; + end if; + end process; +end architecture; + -- cgit v1.2.3