aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Stirling <opensource@mikestirling.co.uk>2011-07-12 20:52:34 +0100
committerMike Stirling <opensource@mikestirling.co.uk>2011-07-12 20:52:34 +0100
commit3975fdfe4275347dab666e43dbfdaebe80c58ff8 (patch)
tree5558fbfb78e6196545fd2fe47465a714d2461e73
downloadfpga-bbc-3975fdfe4275347dab666e43dbfdaebe80c58ff8.tar.gz
fpga-bbc-3975fdfe4275347dab666e43dbfdaebe80c58ff8.tar.bz2
fpga-bbc-3975fdfe4275347dab666e43dbfdaebe80c58ff8.zip
Initial commit. Some modules imported from experimental 6502 platform. Project added for Quartus 9.1
-rw-r--r--CII_Starter_pin_assignments.csv449
-rw-r--r--README2
-rw-r--r--T65/T65.vhd551
-rw-r--r--T65/T65_ALU.vhd260
-rw-r--r--T65/T65_MCode.vhd1052
-rw-r--r--T65/T65_Pack.vhd117
-rw-r--r--bbc_micro.qpf30
-rw-r--r--bbc_micro_de1.qsf503
-rw-r--r--mc6845.vhd419
-rw-r--r--vidproc.vhd192
10 files changed, 3575 insertions, 0 deletions
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;
+