summaryrefslogtreecommitdiffstats
path: root/de1/fpga-bbc-pq/master/line-endings.patch
diff options
context:
space:
mode:
Diffstat (limited to 'de1/fpga-bbc-pq/master/line-endings.patch')
-rw-r--r--de1/fpga-bbc-pq/master/line-endings.patch17558
1 files changed, 17558 insertions, 0 deletions
diff --git a/de1/fpga-bbc-pq/master/line-endings.patch b/de1/fpga-bbc-pq/master/line-endings.patch
new file mode 100644
index 0000000..dd090b6
--- /dev/null
+++ b/de1/fpga-bbc-pq/master/line-endings.patch
@@ -0,0 +1,17558 @@
+diff --git a/CII_Starter_pin_assignments.csv b/CII_Starter_pin_assignments.csv
+index f46adb0..3e1f8de 100644
+--- a/CII_Starter_pin_assignments.csv
++++ b/CII_Starter_pin_assignments.csv
+@@ -1,455 +1,455 @@
+-
+-# 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
+-,FL_CE_N,Location,PIN_AB15,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
+-,SD_nCS,Location,PIN_U20,Yes
+-,SD_MOSI,Location,PIN_Y20,Yes
+-,SD_SCLK,Location,PIN_V20,Yes
+-,SD_MISO,Location,PIN_W20,Yes
+-
++
++# 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
++,FL_CE_N,Location,PIN_AB15,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
++,SD_nCS,Location,PIN_U20,Yes
++,SD_MOSI,Location,PIN_Y20,Yes
++,SD_SCLK,Location,PIN_V20,Yes
++,SD_MISO,Location,PIN_W20,Yes
++
+diff --git a/T65/T65.vhd b/T65/T65.vhd
+index 4a21d79..09253fe 100644
+--- a/T65/T65.vhd
++++ b/T65/T65.vhd
+@@ -1,564 +1,564 @@
+--- ****
+--- 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 /= "00" 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;
+-
+- -- B=1 always on the 6502
+- P(Flag_B) <= '1';
+- if IR = "00000000" and RstCycle = '0' and (NMICycle = '1' or IRQCycle = '1') then
+- if MCycle = "011" then
+- -- B=0 in *copy* of P pushed onto the stack
+- P(Flag_B) <= '0';
+- elsif MCycle = "100" then
+- P(Flag_I) <= '1';
+- end if;
+- 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;
++-- ****
++-- 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 /= "00" 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;
++
++ -- B=1 always on the 6502
++ P(Flag_B) <= '1';
++ if IR = "00000000" and RstCycle = '0' and (NMICycle = '1' or IRQCycle = '1') then
++ if MCycle = "011" then
++ -- B=0 in *copy* of P pushed onto the stack
++ P(Flag_B) <= '0';
++ elsif MCycle = "100" then
++ P(Flag_I) <= '1';
++ end if;
++ 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
+index d9d25e1..b1f6d63 100644
+--- a/T65/T65_ALU.vhd
++++ b/T65/T65_ALU.vhd
+@@ -1,260 +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;
++-- ****
++-- 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
+index 3fd40d8..6c6c864 100644
+--- a/T65/T65_MCode.vhd
++++ b/T65/T65_MCode.vhd
+@@ -1,1052 +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;
++-- ****
++-- 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
+index f8d603c..e025e1b 100644
+--- a/T65/T65_Pack.vhd
++++ b/T65/T65_Pack.vhd
+@@ -1,117 +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;
++-- ****
++-- 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
+index 52e0fd0..c2ade9e 100644
+--- a/bbc_micro.qpf
++++ b/bbc_micro.qpf
+@@ -1,30 +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"
++# -------------------------------------------------------------------------- #
++#
++# 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
+index be8b1f2..0ae4816 100644
+--- a/bbc_micro_de1.qsf
++++ b/bbc_micro_de1.qsf
+@@ -1,537 +1,537 @@
+-# -------------------------------------------------------------------------- #
+-#
+-# 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 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 RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED WITH WEAK PULL-UP"
+-set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
+-set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
+-set_global_assignment -name LL_ROOT_REGION ON -section_id "Root Region"
+-set_global_assignment -name LL_MEMBER_STATE LOCKED -section_id "Root Region"
+-set_global_assignment -name MISC_FILE "U:/git_repos/fpga/bbc/bbc_micro_de1.dpf"
+-set_location_assignment PIN_AB15 -to FL_CE_N
+-set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL"
+-set_global_assignment -name STRATIX_CONFIGURATION_DEVICE EPCS4
+-set_global_assignment -name RESERVE_ASDO_AFTER_CONFIGURATION "AS INPUT TRI-STATED"
+-set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO"
+-set_location_assignment PIN_U20 -to SD_nCS
+-set_location_assignment PIN_V20 -to SD_SCLK
+-set_location_assignment PIN_Y20 -to SD_MOSI
+-set_location_assignment PIN_W20 -to SD_MISO
+-set_global_assignment -name VHDL_FILE saa5050.vhd
+-set_global_assignment -name VHDL_FILE i2s_intf.vhd
+-set_global_assignment -name VHDL_FILE i2c_loader.vhd
+-set_global_assignment -name VHDL_FILE "sn76489-1.0/sn76489_comp_pack-p.vhd"
+-set_global_assignment -name VHDL_FILE "sn76489-1.0/sn76489_noise.vhd"
+-set_global_assignment -name VHDL_FILE "sn76489-1.0/sn76489_tone.vhd"
+-set_global_assignment -name VHDL_FILE "sn76489-1.0/sn76489_top.vhd"
+-set_global_assignment -name VHDL_FILE "sn76489-1.0/sn76489_attenuator.vhd"
+-set_global_assignment -name VHDL_FILE "sn76489-1.0/sn76489_clock_div.vhd"
+-set_global_assignment -name VHDL_FILE "sn76489-1.0/sn76489_latch_ctrl.vhd"
+-set_global_assignment -name VHDL_FILE ps2_intf.vhd
+-set_global_assignment -name VHDL_FILE m6522.vhd
+-set_global_assignment -name VHDL_FILE seg7.vhd
+-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 QIP_FILE pll32.qip
+-set_global_assignment -name VHDL_FILE bbc_micro_de1.vhd
+-set_global_assignment -name VHDL_FILE bbc_micro_de1_tb.vhd
+-set_global_assignment -name VHDL_FILE m6522_tb.vhd
+-set_global_assignment -name VHDL_FILE keyboard.vhd
+-set_global_assignment -name VHDL_FILE debugger.vhd
+-set_global_assignment -name QIP_FILE saa5050_rom.qip
++# -------------------------------------------------------------------------- #
++#
++# 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 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 RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED WITH WEAK PULL-UP"
++set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
++set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
++set_global_assignment -name LL_ROOT_REGION ON -section_id "Root Region"
++set_global_assignment -name LL_MEMBER_STATE LOCKED -section_id "Root Region"
++set_global_assignment -name MISC_FILE "U:/git_repos/fpga/bbc/bbc_micro_de1.dpf"
++set_location_assignment PIN_AB15 -to FL_CE_N
++set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL"
++set_global_assignment -name STRATIX_CONFIGURATION_DEVICE EPCS4
++set_global_assignment -name RESERVE_ASDO_AFTER_CONFIGURATION "AS INPUT TRI-STATED"
++set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO"
++set_location_assignment PIN_U20 -to SD_nCS
++set_location_assignment PIN_V20 -to SD_SCLK
++set_location_assignment PIN_Y20 -to SD_MOSI
++set_location_assignment PIN_W20 -to SD_MISO
++set_global_assignment -name VHDL_FILE saa5050.vhd
++set_global_assignment -name VHDL_FILE i2s_intf.vhd
++set_global_assignment -name VHDL_FILE i2c_loader.vhd
++set_global_assignment -name VHDL_FILE "sn76489-1.0/sn76489_comp_pack-p.vhd"
++set_global_assignment -name VHDL_FILE "sn76489-1.0/sn76489_noise.vhd"
++set_global_assignment -name VHDL_FILE "sn76489-1.0/sn76489_tone.vhd"
++set_global_assignment -name VHDL_FILE "sn76489-1.0/sn76489_top.vhd"
++set_global_assignment -name VHDL_FILE "sn76489-1.0/sn76489_attenuator.vhd"
++set_global_assignment -name VHDL_FILE "sn76489-1.0/sn76489_clock_div.vhd"
++set_global_assignment -name VHDL_FILE "sn76489-1.0/sn76489_latch_ctrl.vhd"
++set_global_assignment -name VHDL_FILE ps2_intf.vhd
++set_global_assignment -name VHDL_FILE m6522.vhd
++set_global_assignment -name VHDL_FILE seg7.vhd
++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 QIP_FILE pll32.qip
++set_global_assignment -name VHDL_FILE bbc_micro_de1.vhd
++set_global_assignment -name VHDL_FILE bbc_micro_de1_tb.vhd
++set_global_assignment -name VHDL_FILE m6522_tb.vhd
++set_global_assignment -name VHDL_FILE keyboard.vhd
++set_global_assignment -name VHDL_FILE debugger.vhd
++set_global_assignment -name QIP_FILE saa5050_rom.qip
+ set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
+\ No newline at end of file
+diff --git a/bbc_micro_de1.vhd b/bbc_micro_de1.vhd
+index e109c36..0fca9de 100644
+--- a/bbc_micro_de1.vhd
++++ b/bbc_micro_de1.vhd
+@@ -1,1265 +1,1265 @@
+--- BBC Micro for Altera DE1
+---
+--- Copyright (c) 2011 Mike Stirling
+---
+--- 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 agreement from the author.
+---
+--- * License is granted for non-commercial use only. A fee may not be charged
+--- for redistributions as source code or in synthesized/hardware form without
+--- specific prior written agreement from the author.
+---
+--- 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.
+---
+--- BBC B Micro
+---
+--- Terasic DE1 top-level
+---
+--- (C) 2011 Mike Stirling
+-
+-library IEEE;
+-use IEEE.STD_LOGIC_1164.ALL;
+-use IEEE.NUMERIC_STD.ALL;
+-
+--- Generic top-level entity for Altera DE1 board
+-entity bbc_micro_de1 is
+-generic (
+- -- ROM offset
+- -- The 4MB Flash is used in 16KB banks as a simple mechanism for
+- -- different machines to address different parts of the ROM, saving
+- -- on re-flashing each time a new machine is run on the board.
+- -- This generic sets the upper 8 address bits.
+- -- Note that the lower bits may be ignored by the implementation,
+- -- e.g. where ROMs are bigger than 16K or where multiple banks
+- -- are required. In this case it is important to ensure that the
+- -- ROM images are aligned correctly (such that these ignored bits are 0).
+- --
+- -- For the BBC the ROMs start in bank 8 (the first 8 banks are used by
+- -- the Spectrum project). The particular bank is selected by the sideways
+- -- ROM paging register, and bank 7 is used for the MOS. Recommended layout
+- -- is:
+- --
+- -- 0 Sideways
+- -- 1 Sideways
+- -- 2 Sideways - SuperMMC (DFS)
+- -- 3 Sideways - BASIC
+- -- 4 Not used
+- -- 5 Not used
+- -- 6 Not used
+- -- 7 MOS
+- ROM_OFFSET : std_logic_vector(7 downto 0) := "00001000"
+- );
+-port (
+- -- Clocks
+- CLOCK_24 : in std_logic_vector(1 downto 0);
+- CLOCK_27 : in std_logic_vector(1 downto 0);
+- CLOCK_50 : in std_logic;
+- EXT_CLOCK : in std_logic;
+-
+- -- Switches
+- SW : in std_logic_vector(9 downto 0);
+- -- Buttons
+- KEY : in std_logic_vector(3 downto 0);
+-
+- -- 7 segment displays
+- HEX0 : out std_logic_vector(6 downto 0);
+- HEX1 : out std_logic_vector(6 downto 0);
+- HEX2 : out std_logic_vector(6 downto 0);
+- HEX3 : out std_logic_vector(6 downto 0);
+- -- Red LEDs
+- LEDR : out std_logic_vector(9 downto 0);
+- -- Green LEDs
+- LEDG : out std_logic_vector(7 downto 0);
+-
+- -- VGA
+- VGA_R : out std_logic_vector(3 downto 0);
+- VGA_G : out std_logic_vector(3 downto 0);
+- VGA_B : out std_logic_vector(3 downto 0);
+- VGA_HS : out std_logic;
+- VGA_VS : out std_logic;
+-
+- -- Serial
+- UART_RXD : in std_logic;
+- UART_TXD : out std_logic;
+-
+- -- PS/2 Keyboard
+- PS2_CLK : inout std_logic;
+- PS2_DAT : inout std_logic;
+-
+- -- I2C
+- I2C_SCLK : inout std_logic;
+- I2C_SDAT : inout std_logic;
+-
+- -- Audio
+- AUD_XCK : out std_logic;
+- AUD_BCLK : out std_logic;
+- AUD_ADCLRCK : out std_logic;
+- AUD_ADCDAT : in std_logic;
+- AUD_DACLRCK : out std_logic;
+- AUD_DACDAT : out std_logic;
+-
+- -- SRAM
+- SRAM_ADDR : out std_logic_vector(17 downto 0);
+- SRAM_DQ : inout std_logic_vector(15 downto 0);
+- SRAM_CE_N : out std_logic;
+- SRAM_OE_N : out std_logic;
+- SRAM_WE_N : out std_logic;
+- SRAM_UB_N : out std_logic;
+- SRAM_LB_N : out std_logic;
+-
+- -- SDRAM
+- DRAM_ADDR : out std_logic_vector(11 downto 0);
+- DRAM_DQ : inout std_logic_vector(15 downto 0);
+- DRAM_BA_0 : in std_logic;
+- DRAM_BA_1 : in std_logic;
+- DRAM_CAS_N : in std_logic;
+- DRAM_CKE : in std_logic;
+- DRAM_CLK : in std_logic;
+- DRAM_CS_N : in std_logic;
+- DRAM_LDQM : in std_logic;
+- DRAM_RAS_N : in std_logic;
+- DRAM_UDQM : in std_logic;
+- DRAM_WE_N : in std_logic;
+-
+- -- Flash
+- FL_ADDR : out std_logic_vector(21 downto 0);
+- FL_DQ : inout std_logic_vector(7 downto 0);
+- FL_RST_N : out std_logic;
+- FL_OE_N : out std_logic;
+- FL_WE_N : out std_logic;
+- FL_CE_N : out std_logic;
+-
+- -- SD card (SPI mode)
+- SD_nCS : out std_logic;
+- SD_MOSI : out std_logic;
+- SD_SCLK : out std_logic;
+- SD_MISO : in std_logic;
+-
+- -- GPIO
+- GPIO_0 : inout std_logic_vector(35 downto 0);
+- GPIO_1 : inout std_logic_vector(35 downto 0)
+- );
+-end entity;
+-
+-architecture rtl of bbc_micro_de1 is
+-
+-------------------------------
+--- PLL (32 MHz master clock)
+-------------------------------
+-
+-component pll32 IS
+- PORT
+- (
+- areset : IN STD_LOGIC := '0';
+- inclk0 : IN STD_LOGIC := '0';
+- c0 : OUT STD_LOGIC ;
+- locked : OUT STD_LOGIC
+- );
+-end component;
+-
+----------
+--- CPU
+----------
+-
+-component 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 component;
+-
+------------------
+--- MC6845 CRTC
+------------------
+-
+-component 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 component;
+-
+--------------------------
+--- "VIDPROC" Video ULA
+--------------------------
+-
+-component 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 component;
+-
+---------------------------------
+--- SAA5050 Teletext Generator
+---------------------------------
+-
+-component saa5050 is
+-port (
+- CLOCK : in std_logic;
+- -- 6 MHz dot clock enable
+- CLKEN : in std_logic;
+- -- Async reset
+- nRESET : in std_logic;
+-
+- -- Character data input (in the bus clock domain)
+- DI_CLOCK : in std_logic;
+- DI_CLKEN : in std_logic;
+- DI : in std_logic_vector(6 downto 0);
+-
+- -- Timing inputs
+- -- General line reset (not used)
+- GLR : in std_logic; -- /HSYNC
+- -- Data entry window - high during VSYNC.
+- -- Resets ROM row counter and drives 'flash' signal
+- DEW : in std_logic; -- VSYNC
+- -- Character rounding select - high during even field
+- CRS : in std_logic; -- FIELD
+- -- Load output shift register enable - high during active video
+- LOSE : in std_logic; -- DE
+-
+- -- Video out
+- R : out std_logic;
+- G : out std_logic;
+- B : out std_logic;
+- Y : out std_logic
+- );
+-end component;
+-
+---------------
+--- 6522 VIA
+---------------
+-
+-component M6522 is
+- port (
+-
+- I_RS : in std_logic_vector(3 downto 0);
+- I_DATA : in std_logic_vector(7 downto 0);
+- O_DATA : out std_logic_vector(7 downto 0);
+- O_DATA_OE_L : out std_logic;
+-
+- I_RW_L : in std_logic;
+- I_CS1 : in std_logic;
+- I_CS2_L : in std_logic;
+-
+- O_IRQ_L : out std_logic; -- note, not open drain
+- -- port a
+- I_CA1 : in std_logic;
+- I_CA2 : in std_logic;
+- O_CA2 : out std_logic;
+- O_CA2_OE_L : out std_logic;
+-
+- I_PA : in std_logic_vector(7 downto 0);
+- O_PA : out std_logic_vector(7 downto 0);
+- O_PA_OE_L : out std_logic_vector(7 downto 0);
+-
+- -- port b
+- I_CB1 : in std_logic;
+- O_CB1 : out std_logic;
+- O_CB1_OE_L : out std_logic;
+-
+- I_CB2 : in std_logic;
+- O_CB2 : out std_logic;
+- O_CB2_OE_L : out std_logic;
+-
+- I_PB : in std_logic_vector(7 downto 0);
+- O_PB : out std_logic_vector(7 downto 0);
+- O_PB_OE_L : out std_logic_vector(7 downto 0);
+-
+- -- FIXME: Revisit timing in this component. Does it really need a 4x clock?
+- I_P2_H : in std_logic; -- high for phase 2 clock ____----__
+- RESET_L : in std_logic;
+- ENA_4 : in std_logic; -- clk enable (4x system clock rate)
+- CLK : in std_logic
+- );
+-end component;
+-
+------------------------------
+--- PS/2 Keyboard Emulation
+------------------------------
+-
+-component keyboard is
+-port (
+- CLOCK : in std_logic;
+- nRESET : in std_logic;
+- CLKEN_1MHZ : in std_logic;
+-
+- -- PS/2 interface
+- PS2_CLK : in std_logic;
+- PS2_DATA : in std_logic;
+-
+- -- If 1 then column is incremented automatically at
+- -- 1 MHz rate
+- AUTOSCAN : in std_logic;
+-
+- COLUMN : in std_logic_vector(3 downto 0);
+- ROW : in std_logic_vector(2 downto 0);
+-
+- -- 1 when currently selected key is down (AUTOSCAN disabled)
+- KEYPRESS : out std_logic;
+- -- 1 when any key is down (except row 0)
+- INT : out std_logic;
+- -- BREAK key output - 1 when pressed
+- BREAK_OUT : out std_logic;
+-
+- -- DIP switch inputs
+- DIP_SWITCH : in std_logic_vector(7 downto 0)
+- );
+-end component;
+-
+------------------------------
+--- SN76489 sound generator
+------------------------------
+-
+-component sn76489_top is
+-
+- generic (
+- clock_div_16_g : integer := 1
+- );
+- port (
+- clock_i : in std_logic;
+- clock_en_i : in std_logic;
+- res_n_i : in std_logic;
+- ce_n_i : in std_logic;
+- we_n_i : in std_logic;
+- ready_o : out std_logic;
+- d_i : in std_logic_vector(0 to 7);
+- aout_o : out signed(0 to 7)
+- );
+-
+-end component;
+-
+-component i2s_intf is
+-generic(
+- mclk_rate : positive := 12000000;
+- sample_rate : positive := 8000;
+- preamble : positive := 1; -- I2S
+- word_length : positive := 16
+- );
+-
+-port (
+- -- 2x MCLK in (e.g. 24 MHz for WM8731 USB mode)
+- CLK : in std_logic;
+- nRESET : in std_logic;
+-
+- -- Parallel IO
+- PCM_INL : out std_logic_vector(word_length - 1 downto 0);
+- PCM_INR : out std_logic_vector(word_length - 1 downto 0);
+- PCM_OUTL : in std_logic_vector(word_length - 1 downto 0);
+- PCM_OUTR : in std_logic_vector(word_length - 1 downto 0);
+-
+- -- Codec interface (right justified mode)
+- -- MCLK is generated at half of the CLK input
+- I2S_MCLK : out std_logic;
+- -- LRCLK is equal to the sample rate and is synchronous to
+- -- MCLK. It must be related to MCLK by the oversampling ratio
+- -- given in the codec datasheet.
+- I2S_LRCLK : out std_logic;
+-
+- -- Data is shifted out on the falling edge of BCLK, sampled
+- -- on the rising edge. The bit rate is determined such that
+- -- it is fast enough to fit preamble + word_length bits into
+- -- each LRCLK half cycle. The last cycle of each word may be
+- -- stretched to fit to LRCLK. This is OK at least for the
+- -- WM8731 codec.
+- -- The first falling edge of each timeslot is always synchronised
+- -- with the LRCLK edge.
+- I2S_BCLK : out std_logic;
+- -- Output bitstream
+- I2S_DOUT : out std_logic;
+- -- Input bitstream
+- I2S_DIN : in std_logic
+- );
+-end component;
+-
+-component i2c_loader is
+-generic (
+- -- Address of slave to be loaded
+- device_address : integer := 16#1a#;
+- -- Number of retries to allow before stopping
+- num_retries : integer := 0;
+- -- Length of clock divider in bits. Resulting bus frequency is
+- -- CLK/2^(log2_divider + 2)
+- log2_divider : integer := 6
+-);
+-
+-port (
+- CLK : in std_logic;
+- nRESET : in std_logic;
+-
+- I2C_SCL : inout std_logic;
+- I2C_SDA : inout std_logic;
+-
+- IS_DONE : out std_logic;
+- IS_ERROR : out std_logic
+- );
+-end component;
+-
+-component debugger is
+-generic (
+- -- Set this for a reasonable half flash duration relative to the
+- -- clock frequency
+- flash_divider : natural := 24
+- );
+-port (
+- CLOCK : in std_logic;
+- nRESET : in std_logic;
+- -- CPU clock enable in
+- CLKEN_IN : in std_logic;
+- -- Gated clock enable back out to CPU
+- CLKEN_OUT : out std_logic;
+- -- CPU IRQ in
+- nIRQ_IN : in std_logic;
+- -- Gated IRQ back out to CPU (no interrupts when single stepping)
+- nIRQ_OUT : out std_logic;
+-
+- -- CPU
+- A_CPU : in std_logic_vector(15 downto 0);
+- R_nW : in std_logic;
+- SYNC : in std_logic;
+-
+- -- Aux bus input for display in hex
+- AUX_BUS : in std_logic_vector(15 downto 0);
+-
+- -- Controls
+- -- RUN or HALT CPU
+- RUN : in std_logic;
+- -- Push button to single-step in HALT mode
+- nSTEP : in std_logic;
+- -- Push button to cycle display mode
+- nMODE : in std_logic;
+- -- Push button to cycle display digit in edit mode
+- nDIGIT : in std_logic;
+- -- Push button to cycle digit value in edit mode
+- nSET : in std_logic;
+-
+- -- Output to display
+- DIGIT3 : out std_logic_vector(6 downto 0);
+- DIGIT2 : out std_logic_vector(6 downto 0);
+- DIGIT1 : out std_logic_vector(6 downto 0);
+- DIGIT0 : out std_logic_vector(6 downto 0);
+-
+- LED_BREAKPOINT : out std_logic;
+- LED_WATCHPOINT : out std_logic
+- );
+-end component;
+-
+--------------
+--- Signals
+--------------
+-
+--- Master clock - 32 MHz
+-signal pll_reset : std_logic;
+-signal pll_locked : std_logic;
+-signal clock : std_logic;
+-signal hard_reset_n : std_logic;
+-signal reset_n : std_logic;
+-
+--- Clock enable counter
+--- CPU and video cycles are interleaved. The CPU runs at 2 MHz (every 16th
+--- cycle) and the video subsystem is enabled on every odd cycle.
+-signal clken_counter : unsigned(4 downto 0);
+-signal cpu_cycle : std_logic; -- Qualifies all 2 MHz cycles
+-signal cpu_cycle_mask : std_logic; -- Set to mask CPU cycles until 1 MHz cycle is complete
+-signal cpu_clken : std_logic; -- 2 MHz cycles in which the CPU is enabled
+-signal cpu_debug_clken : std_logic; -- CPU clken return from hardware debugger
+--- IO cycles are out of phase with the CPU
+-signal vid_clken : std_logic; -- 16 MHz video cycles
+-signal mhz4_clken : std_logic; -- Used by 6522
+-signal mhz2_clken : std_logic; -- Used for latching CPU address for clock stretch
+-signal mhz1_clken : std_logic; -- 1 MHz bus and associated peripherals, 6522 phase 2
+--- SAA5050 needs a 6 MHz clock enable relative to a 24 MHz clock
+-signal ttxt_clken_counter : unsigned(1 downto 0);
+-signal ttxt_clken : std_logic;
+-
+--- Debugger connections
+-signal debug_irq_in_n : std_logic;
+-signal debug_aux : std_logic_vector(15 downto 0);
+-
+--- CPU signals
+-signal cpu_mode : std_logic_vector(1 downto 0);
+-signal cpu_ready : std_logic;
+-signal cpu_abort_n : std_logic;
+-signal cpu_irq_n : std_logic;
+-signal cpu_nmi_n : std_logic;
+-signal cpu_so_n : std_logic;
+-signal cpu_r_nw : std_logic;
+-signal cpu_sync : std_logic;
+-signal cpu_ef : std_logic;
+-signal cpu_mf : std_logic;
+-signal cpu_xf : std_logic;
+-signal cpu_ml_n : std_logic;
+-signal cpu_vp_n : std_logic;
+-signal cpu_vda : std_logic;
+-signal cpu_vpa : std_logic;
+-signal cpu_a : std_logic_vector(23 downto 0);
+-signal cpu_di : std_logic_vector(7 downto 0);
+-signal cpu_do : std_logic_vector(7 downto 0);
+-
+--- CRTC signals
+-signal crtc_clken : std_logic;
+-signal crtc_do : std_logic_vector(7 downto 0);
+-signal crtc_vsync : std_logic;
+-signal crtc_hsync : std_logic;
+-signal crtc_de : std_logic;
+-signal crtc_cursor : std_logic;
+-signal crtc_lpstb : std_logic := '0';
+-signal crtc_ma : std_logic_vector(13 downto 0);
+-signal crtc_ra : std_logic_vector(4 downto 0);
+-
+--- Decoded display address after address translation for hardware
+--- scrolling
+-signal display_a : std_logic_vector(14 downto 0);
+-
+--- "VIDPROC" signals
+-signal vidproc_invert_n : std_logic;
+-signal vidproc_disen : std_logic;
+-signal r_in : std_logic;
+-signal g_in : std_logic;
+-signal b_in : std_logic;
+-signal r_out : std_logic;
+-signal g_out : std_logic;
+-signal b_out : std_logic;
+-
+--- SAA5050 signals
+-signal ttxt_glr : std_logic;
+-signal ttxt_dew : std_logic;
+-signal ttxt_crs : std_logic;
+-signal ttxt_lose : std_logic;
+-signal ttxt_r : std_logic;
+-signal ttxt_g : std_logic;
+-signal ttxt_b : std_logic;
+-signal ttxt_y : std_logic;
+-
+--- System VIA signals
+-signal sys_via_do : std_logic_vector(7 downto 0);
+-signal sys_via_do_oe_n : std_logic;
+-signal sys_via_irq_n : std_logic;
+-signal sys_via_ca1_in : std_logic := '0';
+-signal sys_via_ca2_in : std_logic := '0';
+-signal sys_via_ca2_out : std_logic;
+-signal sys_via_ca2_oe_n : std_logic;
+-signal sys_via_pa_in : std_logic_vector(7 downto 0);
+-signal sys_via_pa_out : std_logic_vector(7 downto 0);
+-signal sys_via_pa_oe_n : std_logic_vector(7 downto 0);
+-signal sys_via_cb1_in : std_logic := '0';
+-signal sys_via_cb1_out : std_logic;
+-signal sys_via_cb1_oe_n : std_logic;
+-signal sys_via_cb2_in : std_logic := '0';
+-signal sys_via_cb2_out : std_logic;
+-signal sys_via_cb2_oe_n : std_logic;
+-signal sys_via_pb_in : std_logic_vector(7 downto 0);
+-signal sys_via_pb_out : std_logic_vector(7 downto 0);
+-signal sys_via_pb_oe_n : std_logic_vector(7 downto 0);
+-
+--- User VIA signals
+-signal user_via_do : std_logic_vector(7 downto 0);
+-signal user_via_do_oe_n : std_logic;
+-signal user_via_irq_n : std_logic;
+-signal user_via_ca1_in : std_logic := '0';
+-signal user_via_ca2_in : std_logic := '0';
+-signal user_via_ca2_out : std_logic;
+-signal user_via_ca2_oe_n : std_logic;
+-signal user_via_pa_in : std_logic_vector(7 downto 0);
+-signal user_via_pa_out : std_logic_vector(7 downto 0);
+-signal user_via_pa_oe_n : std_logic_vector(7 downto 0);
+-signal user_via_cb1_in : std_logic := '0';
+-signal user_via_cb1_out : std_logic;
+-signal user_via_cb1_oe_n : std_logic;
+-signal user_via_cb2_in : std_logic := '0';
+-signal user_via_cb2_out : std_logic;
+-signal user_via_cb2_oe_n : std_logic;
+-signal user_via_pb_in : std_logic_vector(7 downto 0);
+-signal user_via_pb_out : std_logic_vector(7 downto 0);
+-signal user_via_pb_oe_n : std_logic_vector(7 downto 0);
+-
+--- IC32 latch on System VIA
+-signal ic32 : std_logic_vector(7 downto 0);
+-signal sound_enable_n : std_logic;
+-signal speech_read_n : std_logic;
+-signal speech_write_n : std_logic;
+-signal keyb_enable_n : std_logic;
+-signal disp_addr_offs : std_logic_vector(1 downto 0);
+-signal caps_lock_led_n : std_logic;
+-signal shift_lock_led_n : std_logic;
+-
+--- Keyboard
+-signal keyb_column : std_logic_vector(3 downto 0);
+-signal keyb_row : std_logic_vector(2 downto 0);
+-signal keyb_out : std_logic;
+-signal keyb_int : std_logic;
+-signal keyb_break : std_logic;
+-
+--- Sound generator
+-signal sound_ready : std_logic;
+-signal sound_di : std_logic_vector(7 downto 0);
+-signal sound_ao : signed(7 downto 0);
+-signal pcm_inl : std_logic_vector(15 downto 0);
+-signal pcm_inr : std_logic_vector(15 downto 0);
+-
+--- Memory enables
+-signal ram_enable : std_logic; -- 0x0000
+-signal rom_enable : std_logic; -- 0x8000 (BASIC/sideways ROMs)
+-signal mos_enable : std_logic; -- 0xC000
+--- IO region enables
+-signal io_fred : std_logic; -- 0xFC00 (1 MHz bus)
+-signal io_jim : std_logic; -- 0xFD00 (1 MHz bus)
+-signal io_sheila : std_logic; -- 0xFE00 (System peripherals)
+--- SHIELA
+-signal crtc_enable : std_logic; -- 0xFE00-FE07
+-signal acia_enable : std_logic; -- 0xFE08-FE0F
+-signal serproc_enable : std_logic; -- 0xFE10-FE1F
+-signal vidproc_enable : std_logic; -- 0xFE20-FE2F
+-signal romsel_enable : std_logic; -- 0xFE30-FE3F
+-signal sys_via_enable : std_logic; -- 0xFE40-FE5F
+-signal user_via_enable : std_logic; -- 0xFE60-FE7F
+-signal fddc_enable : std_logic; -- 0xFE80-FE9F
+-signal adlc_enable : std_logic; -- 0xFEA0-FEBF (Econet)
+-signal adc_enable : std_logic; -- 0xFEC0-FEDF
+-signal tube_enable : std_logic; -- 0xFEE0-FEFF
+-
+--- ROM select latch
+-signal romsel : std_logic_vector(3 downto 0);
+-
+-signal mhz1_enable : std_logic; -- Set for access to any 1 MHz peripheral
+-
+-begin
+- -------------------------
+- -- COMPONENT INSTANCES
+- -------------------------
+-
+- -- 32 MHz master clock
+- pll: pll32 port map (
+- pll_reset,
+- CLOCK_24(0),
+- clock,
+- pll_locked );
+-
+- -- Hardware debugger block (single-step, breakpoints)
+- debug: debugger port map (
+- clock,
+- hard_reset_n,
+- cpu_clken,
+- cpu_debug_clken,
+- debug_irq_in_n,
+- cpu_irq_n,
+- cpu_a(15 downto 0), cpu_r_nw, cpu_sync,
+- debug_aux,
+- SW(8), -- RUN
+- KEY(3), -- STEP
+- KEY(2), -- MODE
+- KEY(1), -- DIGIT
+- KEY(0), -- SET
+- HEX3, HEX2, HEX1, HEX0,
+- LEDR(3), -- BREAKPOINT
+- LEDR(2) -- WATCHPOINT
+- );
+-
+- -- 6502 CPU
+- cpu : T65 port map (
+- cpu_mode,
+- reset_n,
+- cpu_debug_clken,
+- clock,
+- cpu_ready,
+- cpu_abort_n,
+- cpu_irq_n,
+- cpu_nmi_n,
+- cpu_so_n,
+- cpu_r_nw,
+- cpu_sync,
+- cpu_ef,
+- cpu_mf,
+- cpu_xf,
+- cpu_ml_n,
+- cpu_vp_n,
+- cpu_vda,
+- cpu_vpa,
+- cpu_a,
+- cpu_di,
+- cpu_do );
+-
+- crtc : mc6845 port map (
+- clock,
+- crtc_clken,
+- reset_n,
+- crtc_enable,
+- cpu_r_nw,
+- cpu_a(0),
+- cpu_do,
+- crtc_do,
+- crtc_vsync,
+- crtc_hsync,
+- crtc_de,
+- crtc_cursor,
+- crtc_lpstb,
+- crtc_ma,
+- crtc_ra );
+-
+- video_ula : vidproc port map (
+- clock,
+- vid_clken,
+- reset_n,
+- crtc_clken,
+- vidproc_enable,
+- cpu_a(0),
+- cpu_do,
+- SRAM_DQ(7 downto 0),
+- vidproc_invert_n,
+- vidproc_disen,
+- crtc_cursor,
+- r_in, g_in, b_in,
+- r_out, g_out, b_out
+- );
+-
+- teletext : saa5050 port map (
+- CLOCK_24(0), -- This runs at 6 MHz, which we can't derive from the 32 MHz clock
+- ttxt_clken,
+- reset_n,
+- clock, -- Data input is synchronised from the bus clock domain
+- vid_clken,
+- SRAM_DQ(6 downto 0),
+- ttxt_glr,
+- ttxt_dew,
+- ttxt_crs,
+- ttxt_lose,
+- ttxt_r, ttxt_g, ttxt_b, ttxt_y
+- );
+-
+- -- System VIA
+- system_via : m6522 port map (
+- cpu_a(3 downto 0),
+- cpu_do,
+- sys_via_do,
+- sys_via_do_oe_n,
+- cpu_r_nw,
+- sys_via_enable,
+- '0', -- nCS2
+- sys_via_irq_n,
+- sys_via_ca1_in,
+- sys_via_ca2_in,
+- sys_via_ca2_out,
+- sys_via_ca2_oe_n,
+- sys_via_pa_in,
+- sys_via_pa_out,
+- sys_via_pa_oe_n,
+- sys_via_cb1_in,
+- sys_via_cb1_out,
+- sys_via_cb1_oe_n,
+- sys_via_cb2_in,
+- sys_via_cb2_out,
+- sys_via_cb2_oe_n,
+- sys_via_pb_in,
+- sys_via_pb_out,
+- sys_via_pb_oe_n,
+- mhz1_clken,
+- hard_reset_n, -- System VIA is reset by power on reset only
+- mhz4_clken,
+- clock
+- );
+-
+- -- User VIA
+- user_via : m6522 port map (
+- cpu_a(3 downto 0),
+- cpu_do,
+- user_via_do,
+- user_via_do_oe_n,
+- cpu_r_nw,
+- user_via_enable,
+- '0', -- nCS2
+- user_via_irq_n,
+- user_via_ca1_in,
+- user_via_ca2_in,
+- user_via_ca2_out,
+- user_via_ca2_oe_n,
+- user_via_pa_in,
+- user_via_pa_out,
+- user_via_pa_oe_n,
+- user_via_cb1_in,
+- user_via_cb1_out,
+- user_via_cb1_oe_n,
+- user_via_cb2_in,
+- user_via_cb2_out,
+- user_via_cb2_oe_n,
+- user_via_pb_in,
+- user_via_pb_out,
+- user_via_pb_oe_n,
+- mhz1_clken,
+- reset_n,
+- mhz4_clken,
+- clock
+- );
+-
+- -- Keyboard
+- keyb : keyboard port map (
+- clock, hard_reset_n, mhz1_clken,
+- PS2_CLK, PS2_DAT,
+- keyb_enable_n,
+- keyb_column,
+- keyb_row,
+- keyb_out,
+- keyb_int,
+- keyb_break,
+- SW(7 downto 0)
+- );
+-
+- -- Sound generator (and drive logic for I2S codec)
+- sound : sn76489_top port map (
+- clock, mhz4_clken,
+- reset_n, '0', sound_enable_n,
+- sound_ready, sound_di,
+- sound_ao
+- );
+- i2s : i2s_intf port map (
+- CLOCK_24(0), reset_n,
+- pcm_inl, pcm_inr,
+- std_logic_vector(sound_ao) & "00000000",
+- std_logic_vector(sound_ao) & "00000000",
+- AUD_XCK, AUD_DACLRCK,
+- AUD_BCLK, AUD_DACDAT, AUD_ADCDAT
+- );
+- i2c : i2c_loader
+- generic map (
+- log2_divider => 7
+- )
+- port map (
+- clock, reset_n,
+- I2C_SCLK, I2C_SDAT,
+- LEDR(5), -- IS_DONE
+- LEDR(4) -- IS_ERROR
+- );
+-
+- -- Asynchronous reset
+- -- PLL is reset by external reset switch
+- pll_reset <= not SW(9);
+- -- Keyboard and System VIA are reset by external reset switch or PLL being out of lock
+- hard_reset_n <= not (pll_reset or not pll_locked);
+- -- Rest of system is reset by all of the above plus the keyboard BREAK key
+- reset_n <= hard_reset_n and not keyb_break;
+-
+- -- Clock enable generation - 32 MHz clock split into 32 cycles
+- -- CPU is on 0 and 16 (but can be masked by 1 MHz bus accesses)
+- -- Video is on all odd cycles (16 MHz)
+- -- 1 MHz cycles are on cycle 31 (1 MHz)
+- vid_clken <= clken_counter(0); -- 1,3,5...
+- mhz4_clken <= clken_counter(0) and clken_counter(1) and clken_counter(2); -- 7/15/23/31
+- mhz2_clken <= mhz4_clken and clken_counter(3); -- 15/31
+- mhz1_clken <= mhz2_clken and clken_counter(4); -- 31
+- cpu_cycle <= not (clken_counter(0) or clken_counter(1) or clken_counter(2) or clken_counter(3)); -- 0/16
+- cpu_clken <= cpu_cycle and not cpu_cycle_mask;
+-
+- clk_gen: process(clock,reset_n)
+- begin
+- if reset_n = '0' then
+- clken_counter <= (others => '0');
+- elsif rising_edge(clock) then
+- clken_counter <= clken_counter + 1;
+- end if;
+- end process;
+-
+- cycle_stretch: process(clock,reset_n)
+- begin
+- if reset_n = '0' then
+- cpu_cycle_mask <= '0';
+- elsif rising_edge(clock) and mhz2_clken = '1' then
+- if mhz1_enable = '1' and cpu_cycle_mask = '0' then
+- -- Block CPU cycles until 1 MHz cycle has completed
+- cpu_cycle_mask <= '1';
+- end if;
+- if mhz1_clken = '1' then
+- -- CPU can run again
+- -- FIXME: This may not be correct in terms of CPU cycles, but it
+- -- should work
+- cpu_cycle_mask <= '0';
+- end if;
+- end if;
+- end process;
+-
+- ttxt_clk_gen: process(CLOCK_24(0),reset_n)
+- begin
+- if reset_n = '0' then
+- ttxt_clken_counter <= (others => '0');
+- elsif rising_edge(CLOCK_24(0)) then
+- ttxt_clken_counter <= ttxt_clken_counter + 1;
+- end if;
+- end process;
+-
+- -- 6 MHz clock enable for SAA5050
+- ttxt_clken <= '1' when ttxt_clken_counter = 0 else '0';
+-
+- -- CPU configuration and fixed signals
+- cpu_mode <= "00"; -- 6502
+- cpu_ready <= '1';
+- cpu_abort_n <= '1';
+- cpu_nmi_n <= '1';
+- cpu_so_n <= '1';
+-
+- -- Address decoding
+- -- 0x0000 = 32 KB SRAM
+- -- 0x8000 = 16 KB BASIC/Sideways ROMs
+- -- 0xC000 = 16 KB MOS ROM
+- --
+- -- IO regions are mapped into a hole in the MOS. There are three regions:
+- -- 0xFC00 = FRED
+- -- 0xFD00 = JIM
+- -- 0xFE00 = SHEILA
+- ram_enable <= not cpu_a(15);
+- rom_enable <= cpu_a(15) and not cpu_a(14);
+- mos_enable <= cpu_a(15) and cpu_a(14) and not (io_fred or io_jim or io_sheila);
+- io_fred <= '1' when cpu_a(15 downto 8) = "11111100" else '0';
+- io_jim <= '1' when cpu_a(15 downto 8) = "11111101" else '0';
+- io_sheila <= '1' when cpu_a(15 downto 8) = "11111110" else '0';
+- -- The following IO regions are accessed at 1 MHz and hence will stall the
+- -- CPU accordingly
+- mhz1_enable <= io_fred or io_jim or
+- adc_enable or sys_via_enable or user_via_enable or
+- serproc_enable or acia_enable or crtc_enable;
+-
+- -- SHEILA address demux
+- -- All the system peripherals are mapped into this page as follows:
+- -- 0xFE00 - 0xFE07 = MC6845 CRTC
+- -- 0xFE08 - 0xFE0F = MC6850 ACIA (Serial/Tape)
+- -- 0xFE10 - 0xFE1F = Serial ULA
+- -- 0xFE20 - 0xFE2F = Video ULA
+- -- 0xFE30 - 0xFE3F = Paged ROM select latch
+- -- 0xFE40 - 0xFE5F = System VIA (6522)
+- -- 0xFE60 - 0xFE7F = User VIA (6522)
+- -- 0xFE80 - 0xFE9F = 8271 Floppy disc controller
+- -- 0xFEA0 - 0xFEBF = 68B54 ADLC for Econet
+- -- 0xFEC0 - 0xFEDF = uPD7002 ADC
+- -- 0xFEE0 - 0xFEFF = Tube ULA
+- process(cpu_a,io_sheila)
+- begin
+- -- All regions normally de-selected
+- crtc_enable <= '0';
+- acia_enable <= '0';
+- serproc_enable <= '0';
+- vidproc_enable <= '0';
+- romsel_enable <= '0';
+- sys_via_enable <= '0';
+- user_via_enable <= '0';
+- fddc_enable <= '0';
+- adlc_enable <= '0';
+- adc_enable <= '0';
+- tube_enable <= '0';
+-
+- if io_sheila = '1' then
+- case cpu_a(7 downto 5) is
+- when "000" =>
+- -- 0xFE00
+- if cpu_a(4) = '0' then
+- if cpu_a(3) = '0' then
+- -- 0xFE00
+- crtc_enable <= '1';
+- else
+- -- 0xFE08
+- acia_enable <= '1';
+- end if;
+- else
+- -- 0xFE10
+- serproc_enable <= '1';
+- end if;
+- when "001" =>
+- -- 0xFE20
+- if cpu_a(4) = '0' then
+- -- 0xFE20
+- vidproc_enable <= '1';
+- else
+- -- 0xFE30
+- romsel_enable <= '1';
+- end if;
+- when "010" => sys_via_enable <= '1'; -- 0xFE40
+- when "011" => user_via_enable <= '1'; -- 0xFE60
+- when "100" => fddc_enable <= '1'; -- 0xFE80
+- when "101" => adlc_enable <= '1'; -- 0xFEA0
+- when "110" => adc_enable <= '1'; -- 0xFEC0
+- when "111" => tube_enable <= '1'; -- 0xFEE0
+- when others =>
+- null;
+- end case;
+- end if;
+- end process;
+-
+- -- CPU data bus mux and interrupts
+- cpu_di <=
+- SRAM_DQ(7 downto 0) when ram_enable = '1' else
+- FL_DQ when rom_enable = '1' else
+- FL_DQ when mos_enable = '1' else
+- crtc_do when crtc_enable = '1' else
+- "00000010" when acia_enable = '1' else
+- sys_via_do when sys_via_enable = '1' else
+- user_via_do when user_via_enable = '1' else
+- (others => '0'); -- un-decoded locations are pulled down by RP1
+- debug_irq_in_n <= sys_via_irq_n and user_via_irq_n; -- route IRQ through debugger
+- --cpu_irq_n <= sys_via_irq_n and user_via_irq_n;
+-
+- -- ROMs are in external flash and split into 16K slots (since this also suits other
+- -- computers that might be run on the same board).
+- -- The first 8 slots are allocated for use here, and the first 4 are decoded as
+- -- the sideways ROMs. Slot 7 is used for the MOS.
+- FL_RST_N <= reset_n;
+- FL_CE_N <= '0';
+- FL_OE_N <= '0';
+- FL_WE_N <= '1';
+- FL_ADDR(21 downto 17) <= ROM_OFFSET(7 downto 3);
+- FL_ADDR(16 downto 14) <=
+- "111" when mos_enable = '1' else
+- "0" & romsel(1 downto 0);
+- FL_ADDR(13 downto 0) <= cpu_a(13 downto 0);
+-
+- -- SRAM bus
+- SRAM_UB_N <= '1';
+- SRAM_LB_N <= '0';
+- SRAM_CE_N <= '0';
+- SRAM_OE_N <= '0';
+- SRAM_DQ(15 downto 8) <= (others => '0');
+-
+- -- Synchronous outputs to SRAM
+- process(clock,reset_n)
+- variable ram_write : std_logic;
+- begin
+- ram_write := ram_enable and not cpu_r_nw;
+-
+- if reset_n = '0' then
+- SRAM_WE_N <= '1';
+- SRAM_DQ(7 downto 0) <= (others => 'Z');
+- elsif rising_edge(clock) then
+- -- Default to inputs
+- SRAM_DQ(7 downto 0) <= (others => 'Z');
+-
+- -- Register SRAM signals to outputs (clock must be at least 2x CPU clock)
+- if vid_clken = '1' then
+- -- Fetch data from previous CPU cycle
+- SRAM_WE_N <= not ram_write;
+- SRAM_ADDR <= "00" & cpu_a(15 downto 0);
+- if ram_write = '1' then
+- SRAM_DQ(7 downto 0) <= cpu_do;
+- end if;
+- else
+- -- Fetch data from previous display cycle
+- SRAM_WE_N <= '1';
+- SRAM_ADDR <= "000" & display_a;
+- end if;
+- end if;
+- end process;
+-
+- -- Address translation logic for calculation of display address
+- process(crtc_ma,crtc_ra,disp_addr_offs)
+- variable aa : unsigned(3 downto 0);
+- begin
+- if crtc_ma(12) = '0' then
+- -- No adjustment
+- aa := unsigned(crtc_ma(11 downto 8));
+- else
+- -- Address adjusted according to screen mode to compensate for
+- -- wrap at 0x8000.
+- case disp_addr_offs is
+- when "00" =>
+- -- Mode 3 - restart at 0x4000
+- aa := unsigned(crtc_ma(11 downto 8)) + 8;
+- when "01" =>
+- -- Mode 6 - restart at 0x6000
+- aa := unsigned(crtc_ma(11 downto 8)) + 12;
+- when "10" =>
+- -- Mode 0,1,2 - restart at 0x3000
+- aa := unsigned(crtc_ma(11 downto 8)) + 6;
+- when "11" =>
+- -- Mode 4,5 - restart at 0x5800
+- aa := unsigned(crtc_ma(11 downto 8)) + 11;
+- when others =>
+- null;
+- end case;
+- end if;
+-
+- if crtc_ma(13) = '0' then
+- -- HI RES
+- display_a <= std_logic_vector(aa(3 downto 0)) & crtc_ma(7 downto 0) & crtc_ra(2 downto 0);
+- else
+- -- TTX VDU
+- display_a <= std_logic(aa(3)) & "1111" & crtc_ma(9 downto 0);
+- end if;
+- end process;
+-
+- -- VIDPROC
+- vidproc_invert_n <= '1';
+- vidproc_disen <= crtc_de and not crtc_ra(3); -- DISEN is masked off by RA(3) for MODEs 3 and 6
+- r_in <= ttxt_r;
+- g_in <= ttxt_g;
+- b_in <= ttxt_b;
+-
+- -- SAA5050
+- ttxt_glr <= not crtc_hsync;
+- ttxt_dew <= crtc_vsync;
+- ttxt_crs <= not crtc_ra(0);
+- ttxt_lose <= crtc_de;
+-
+- -- CRTC drives video out (CSYNC on HSYNC output, VSYNC high)
+- VGA_HS <= not (crtc_hsync xor crtc_vsync);
+- VGA_VS <= '1';
+- VGA_R <= r_out & r_out & r_out & r_out;
+- VGA_G <= g_out & g_out & g_out & g_out;
+- VGA_B <= b_out & b_out & b_out & b_out;
+-
+- -- Connections to System VIA
+- -- ADC
+- sys_via_cb1_in <= '1'; -- /EOC
+- -- CRTC
+- sys_via_ca1_in <= crtc_vsync;
+- sys_via_cb2_in <= crtc_lpstb;
+- -- Keyboard
+- sys_via_ca2_in <= keyb_int;
+- sys_via_pa_in(7) <= keyb_out;
+- sys_via_pa_in(6 downto 0) <= sys_via_pa_out(6 downto 0); -- Must loop back output pins or keyboard won't work
+- keyb_column <= sys_via_pa_out(3 downto 0);
+- keyb_row <= sys_via_pa_out(6 downto 4);
+- -- Sound
+- sound_di <= sys_via_pa_out;
+- -- Others (idle until missing bits implemented)
+- sys_via_pb_in(7 downto 4) <= (others => '1');
+-
+- -- Connections to User VIA (user port is output on green LEDs)
+- user_via_ca1_in <= '1'; -- Pulled up
+- --LEDG <= user_via_pb_out;
+-
+- -- MMBEEB
+- user_via_cb1_in <= user_via_pb_out(1);
+- SD_SCLK <= user_via_pb_out(1); -- SCLK
+- SD_MOSI <= user_via_pb_out(0); -- SDO
+- SD_nCS <= '0'; -- CS
+- user_via_cb2_in <= SD_MISO; -- SDI
+- user_via_pb_in <= user_via_pb_out;
+-
+- -- ROM select latch
+- process(clock,reset_n)
+- begin
+- if reset_n = '0' then
+- romsel <= (others => '0');
+- elsif rising_edge(clock) then
+- if romsel_enable = '1' and cpu_r_nw = '0' then
+- romsel <= cpu_do(3 downto 0);
+- end if;
+- end if;
+- end process;
+-
+- -- IC32 latch
+- sound_enable_n <= ic32(0);
+- speech_write_n <= ic32(1);
+- speech_read_n <= ic32(2);
+- keyb_enable_n <= ic32(3);
+- disp_addr_offs <= ic32(5 downto 4);
+- caps_lock_led_n <= ic32(6);
+- shift_lock_led_n <= ic32(7);
+-
+- process(clock,reset_n)
+- variable bit_num : integer;
+- begin
+- bit_num := to_integer(unsigned(sys_via_pb_out(2 downto 0)));
+-
+- if reset_n = '0' then
+- ic32 <= (others => '0');
+- elsif rising_edge(clock) then
+- ic32(bit_num) <= sys_via_pb_out(3);
+- end if;
+- end process;
+-
+- -- Keyboard LEDs
+- LEDR(0) <= not caps_lock_led_n;
+- LEDR(1) <= not shift_lock_led_n;
+-
+- -----------------
+- -- DEBUG STUFF
+- -----------------
+-
+- GPIO_0(0) <= not (crtc_hsync xor crtc_vsync);
+- GPIO_0(1) <= crtc_de;
+-
+-end architecture;
++-- BBC Micro for Altera DE1
++--
++-- Copyright (c) 2011 Mike Stirling
++--
++-- 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 agreement from the author.
++--
++-- * License is granted for non-commercial use only. A fee may not be charged
++-- for redistributions as source code or in synthesized/hardware form without
++-- specific prior written agreement from the author.
++--
++-- 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.
++--
++-- BBC B Micro
++--
++-- Terasic DE1 top-level
++--
++-- (C) 2011 Mike Stirling
++
++library IEEE;
++use IEEE.STD_LOGIC_1164.ALL;
++use IEEE.NUMERIC_STD.ALL;
++
++-- Generic top-level entity for Altera DE1 board
++entity bbc_micro_de1 is
++generic (
++ -- ROM offset
++ -- The 4MB Flash is used in 16KB banks as a simple mechanism for
++ -- different machines to address different parts of the ROM, saving
++ -- on re-flashing each time a new machine is run on the board.
++ -- This generic sets the upper 8 address bits.
++ -- Note that the lower bits may be ignored by the implementation,
++ -- e.g. where ROMs are bigger than 16K or where multiple banks
++ -- are required. In this case it is important to ensure that the
++ -- ROM images are aligned correctly (such that these ignored bits are 0).
++ --
++ -- For the BBC the ROMs start in bank 8 (the first 8 banks are used by
++ -- the Spectrum project). The particular bank is selected by the sideways
++ -- ROM paging register, and bank 7 is used for the MOS. Recommended layout
++ -- is:
++ --
++ -- 0 Sideways
++ -- 1 Sideways
++ -- 2 Sideways - SuperMMC (DFS)
++ -- 3 Sideways - BASIC
++ -- 4 Not used
++ -- 5 Not used
++ -- 6 Not used
++ -- 7 MOS
++ ROM_OFFSET : std_logic_vector(7 downto 0) := "00001000"
++ );
++port (
++ -- Clocks
++ CLOCK_24 : in std_logic_vector(1 downto 0);
++ CLOCK_27 : in std_logic_vector(1 downto 0);
++ CLOCK_50 : in std_logic;
++ EXT_CLOCK : in std_logic;
++
++ -- Switches
++ SW : in std_logic_vector(9 downto 0);
++ -- Buttons
++ KEY : in std_logic_vector(3 downto 0);
++
++ -- 7 segment displays
++ HEX0 : out std_logic_vector(6 downto 0);
++ HEX1 : out std_logic_vector(6 downto 0);
++ HEX2 : out std_logic_vector(6 downto 0);
++ HEX3 : out std_logic_vector(6 downto 0);
++ -- Red LEDs
++ LEDR : out std_logic_vector(9 downto 0);
++ -- Green LEDs
++ LEDG : out std_logic_vector(7 downto 0);
++
++ -- VGA
++ VGA_R : out std_logic_vector(3 downto 0);
++ VGA_G : out std_logic_vector(3 downto 0);
++ VGA_B : out std_logic_vector(3 downto 0);
++ VGA_HS : out std_logic;
++ VGA_VS : out std_logic;
++
++ -- Serial
++ UART_RXD : in std_logic;
++ UART_TXD : out std_logic;
++
++ -- PS/2 Keyboard
++ PS2_CLK : inout std_logic;
++ PS2_DAT : inout std_logic;
++
++ -- I2C
++ I2C_SCLK : inout std_logic;
++ I2C_SDAT : inout std_logic;
++
++ -- Audio
++ AUD_XCK : out std_logic;
++ AUD_BCLK : out std_logic;
++ AUD_ADCLRCK : out std_logic;
++ AUD_ADCDAT : in std_logic;
++ AUD_DACLRCK : out std_logic;
++ AUD_DACDAT : out std_logic;
++
++ -- SRAM
++ SRAM_ADDR : out std_logic_vector(17 downto 0);
++ SRAM_DQ : inout std_logic_vector(15 downto 0);
++ SRAM_CE_N : out std_logic;
++ SRAM_OE_N : out std_logic;
++ SRAM_WE_N : out std_logic;
++ SRAM_UB_N : out std_logic;
++ SRAM_LB_N : out std_logic;
++
++ -- SDRAM
++ DRAM_ADDR : out std_logic_vector(11 downto 0);
++ DRAM_DQ : inout std_logic_vector(15 downto 0);
++ DRAM_BA_0 : in std_logic;
++ DRAM_BA_1 : in std_logic;
++ DRAM_CAS_N : in std_logic;
++ DRAM_CKE : in std_logic;
++ DRAM_CLK : in std_logic;
++ DRAM_CS_N : in std_logic;
++ DRAM_LDQM : in std_logic;
++ DRAM_RAS_N : in std_logic;
++ DRAM_UDQM : in std_logic;
++ DRAM_WE_N : in std_logic;
++
++ -- Flash
++ FL_ADDR : out std_logic_vector(21 downto 0);
++ FL_DQ : inout std_logic_vector(7 downto 0);
++ FL_RST_N : out std_logic;
++ FL_OE_N : out std_logic;
++ FL_WE_N : out std_logic;
++ FL_CE_N : out std_logic;
++
++ -- SD card (SPI mode)
++ SD_nCS : out std_logic;
++ SD_MOSI : out std_logic;
++ SD_SCLK : out std_logic;
++ SD_MISO : in std_logic;
++
++ -- GPIO
++ GPIO_0 : inout std_logic_vector(35 downto 0);
++ GPIO_1 : inout std_logic_vector(35 downto 0)
++ );
++end entity;
++
++architecture rtl of bbc_micro_de1 is
++
++------------------------------
++-- PLL (32 MHz master clock)
++------------------------------
++
++component pll32 IS
++ PORT
++ (
++ areset : IN STD_LOGIC := '0';
++ inclk0 : IN STD_LOGIC := '0';
++ c0 : OUT STD_LOGIC ;
++ locked : OUT STD_LOGIC
++ );
++end component;
++
++---------
++-- CPU
++---------
++
++component 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 component;
++
++-----------------
++-- MC6845 CRTC
++-----------------
++
++component 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 component;
++
++-------------------------
++-- "VIDPROC" Video ULA
++-------------------------
++
++component 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 component;
++
++--------------------------------
++-- SAA5050 Teletext Generator
++--------------------------------
++
++component saa5050 is
++port (
++ CLOCK : in std_logic;
++ -- 6 MHz dot clock enable
++ CLKEN : in std_logic;
++ -- Async reset
++ nRESET : in std_logic;
++
++ -- Character data input (in the bus clock domain)
++ DI_CLOCK : in std_logic;
++ DI_CLKEN : in std_logic;
++ DI : in std_logic_vector(6 downto 0);
++
++ -- Timing inputs
++ -- General line reset (not used)
++ GLR : in std_logic; -- /HSYNC
++ -- Data entry window - high during VSYNC.
++ -- Resets ROM row counter and drives 'flash' signal
++ DEW : in std_logic; -- VSYNC
++ -- Character rounding select - high during even field
++ CRS : in std_logic; -- FIELD
++ -- Load output shift register enable - high during active video
++ LOSE : in std_logic; -- DE
++
++ -- Video out
++ R : out std_logic;
++ G : out std_logic;
++ B : out std_logic;
++ Y : out std_logic
++ );
++end component;
++
++--------------
++-- 6522 VIA
++--------------
++
++component M6522 is
++ port (
++
++ I_RS : in std_logic_vector(3 downto 0);
++ I_DATA : in std_logic_vector(7 downto 0);
++ O_DATA : out std_logic_vector(7 downto 0);
++ O_DATA_OE_L : out std_logic;
++
++ I_RW_L : in std_logic;
++ I_CS1 : in std_logic;
++ I_CS2_L : in std_logic;
++
++ O_IRQ_L : out std_logic; -- note, not open drain
++ -- port a
++ I_CA1 : in std_logic;
++ I_CA2 : in std_logic;
++ O_CA2 : out std_logic;
++ O_CA2_OE_L : out std_logic;
++
++ I_PA : in std_logic_vector(7 downto 0);
++ O_PA : out std_logic_vector(7 downto 0);
++ O_PA_OE_L : out std_logic_vector(7 downto 0);
++
++ -- port b
++ I_CB1 : in std_logic;
++ O_CB1 : out std_logic;
++ O_CB1_OE_L : out std_logic;
++
++ I_CB2 : in std_logic;
++ O_CB2 : out std_logic;
++ O_CB2_OE_L : out std_logic;
++
++ I_PB : in std_logic_vector(7 downto 0);
++ O_PB : out std_logic_vector(7 downto 0);
++ O_PB_OE_L : out std_logic_vector(7 downto 0);
++
++ -- FIXME: Revisit timing in this component. Does it really need a 4x clock?
++ I_P2_H : in std_logic; -- high for phase 2 clock ____----__
++ RESET_L : in std_logic;
++ ENA_4 : in std_logic; -- clk enable (4x system clock rate)
++ CLK : in std_logic
++ );
++end component;
++
++-----------------------------
++-- PS/2 Keyboard Emulation
++-----------------------------
++
++component keyboard is
++port (
++ CLOCK : in std_logic;
++ nRESET : in std_logic;
++ CLKEN_1MHZ : in std_logic;
++
++ -- PS/2 interface
++ PS2_CLK : in std_logic;
++ PS2_DATA : in std_logic;
++
++ -- If 1 then column is incremented automatically at
++ -- 1 MHz rate
++ AUTOSCAN : in std_logic;
++
++ COLUMN : in std_logic_vector(3 downto 0);
++ ROW : in std_logic_vector(2 downto 0);
++
++ -- 1 when currently selected key is down (AUTOSCAN disabled)
++ KEYPRESS : out std_logic;
++ -- 1 when any key is down (except row 0)
++ INT : out std_logic;
++ -- BREAK key output - 1 when pressed
++ BREAK_OUT : out std_logic;
++
++ -- DIP switch inputs
++ DIP_SWITCH : in std_logic_vector(7 downto 0)
++ );
++end component;
++
++-----------------------------
++-- SN76489 sound generator
++-----------------------------
++
++component sn76489_top is
++
++ generic (
++ clock_div_16_g : integer := 1
++ );
++ port (
++ clock_i : in std_logic;
++ clock_en_i : in std_logic;
++ res_n_i : in std_logic;
++ ce_n_i : in std_logic;
++ we_n_i : in std_logic;
++ ready_o : out std_logic;
++ d_i : in std_logic_vector(0 to 7);
++ aout_o : out signed(0 to 7)
++ );
++
++end component;
++
++component i2s_intf is
++generic(
++ mclk_rate : positive := 12000000;
++ sample_rate : positive := 8000;
++ preamble : positive := 1; -- I2S
++ word_length : positive := 16
++ );
++
++port (
++ -- 2x MCLK in (e.g. 24 MHz for WM8731 USB mode)
++ CLK : in std_logic;
++ nRESET : in std_logic;
++
++ -- Parallel IO
++ PCM_INL : out std_logic_vector(word_length - 1 downto 0);
++ PCM_INR : out std_logic_vector(word_length - 1 downto 0);
++ PCM_OUTL : in std_logic_vector(word_length - 1 downto 0);
++ PCM_OUTR : in std_logic_vector(word_length - 1 downto 0);
++
++ -- Codec interface (right justified mode)
++ -- MCLK is generated at half of the CLK input
++ I2S_MCLK : out std_logic;
++ -- LRCLK is equal to the sample rate and is synchronous to
++ -- MCLK. It must be related to MCLK by the oversampling ratio
++ -- given in the codec datasheet.
++ I2S_LRCLK : out std_logic;
++
++ -- Data is shifted out on the falling edge of BCLK, sampled
++ -- on the rising edge. The bit rate is determined such that
++ -- it is fast enough to fit preamble + word_length bits into
++ -- each LRCLK half cycle. The last cycle of each word may be
++ -- stretched to fit to LRCLK. This is OK at least for the
++ -- WM8731 codec.
++ -- The first falling edge of each timeslot is always synchronised
++ -- with the LRCLK edge.
++ I2S_BCLK : out std_logic;
++ -- Output bitstream
++ I2S_DOUT : out std_logic;
++ -- Input bitstream
++ I2S_DIN : in std_logic
++ );
++end component;
++
++component i2c_loader is
++generic (
++ -- Address of slave to be loaded
++ device_address : integer := 16#1a#;
++ -- Number of retries to allow before stopping
++ num_retries : integer := 0;
++ -- Length of clock divider in bits. Resulting bus frequency is
++ -- CLK/2^(log2_divider + 2)
++ log2_divider : integer := 6
++);
++
++port (
++ CLK : in std_logic;
++ nRESET : in std_logic;
++
++ I2C_SCL : inout std_logic;
++ I2C_SDA : inout std_logic;
++
++ IS_DONE : out std_logic;
++ IS_ERROR : out std_logic
++ );
++end component;
++
++component debugger is
++generic (
++ -- Set this for a reasonable half flash duration relative to the
++ -- clock frequency
++ flash_divider : natural := 24
++ );
++port (
++ CLOCK : in std_logic;
++ nRESET : in std_logic;
++ -- CPU clock enable in
++ CLKEN_IN : in std_logic;
++ -- Gated clock enable back out to CPU
++ CLKEN_OUT : out std_logic;
++ -- CPU IRQ in
++ nIRQ_IN : in std_logic;
++ -- Gated IRQ back out to CPU (no interrupts when single stepping)
++ nIRQ_OUT : out std_logic;
++
++ -- CPU
++ A_CPU : in std_logic_vector(15 downto 0);
++ R_nW : in std_logic;
++ SYNC : in std_logic;
++
++ -- Aux bus input for display in hex
++ AUX_BUS : in std_logic_vector(15 downto 0);
++
++ -- Controls
++ -- RUN or HALT CPU
++ RUN : in std_logic;
++ -- Push button to single-step in HALT mode
++ nSTEP : in std_logic;
++ -- Push button to cycle display mode
++ nMODE : in std_logic;
++ -- Push button to cycle display digit in edit mode
++ nDIGIT : in std_logic;
++ -- Push button to cycle digit value in edit mode
++ nSET : in std_logic;
++
++ -- Output to display
++ DIGIT3 : out std_logic_vector(6 downto 0);
++ DIGIT2 : out std_logic_vector(6 downto 0);
++ DIGIT1 : out std_logic_vector(6 downto 0);
++ DIGIT0 : out std_logic_vector(6 downto 0);
++
++ LED_BREAKPOINT : out std_logic;
++ LED_WATCHPOINT : out std_logic
++ );
++end component;
++
++-------------
++-- Signals
++-------------
++
++-- Master clock - 32 MHz
++signal pll_reset : std_logic;
++signal pll_locked : std_logic;
++signal clock : std_logic;
++signal hard_reset_n : std_logic;
++signal reset_n : std_logic;
++
++-- Clock enable counter
++-- CPU and video cycles are interleaved. The CPU runs at 2 MHz (every 16th
++-- cycle) and the video subsystem is enabled on every odd cycle.
++signal clken_counter : unsigned(4 downto 0);
++signal cpu_cycle : std_logic; -- Qualifies all 2 MHz cycles
++signal cpu_cycle_mask : std_logic; -- Set to mask CPU cycles until 1 MHz cycle is complete
++signal cpu_clken : std_logic; -- 2 MHz cycles in which the CPU is enabled
++signal cpu_debug_clken : std_logic; -- CPU clken return from hardware debugger
++-- IO cycles are out of phase with the CPU
++signal vid_clken : std_logic; -- 16 MHz video cycles
++signal mhz4_clken : std_logic; -- Used by 6522
++signal mhz2_clken : std_logic; -- Used for latching CPU address for clock stretch
++signal mhz1_clken : std_logic; -- 1 MHz bus and associated peripherals, 6522 phase 2
++-- SAA5050 needs a 6 MHz clock enable relative to a 24 MHz clock
++signal ttxt_clken_counter : unsigned(1 downto 0);
++signal ttxt_clken : std_logic;
++
++-- Debugger connections
++signal debug_irq_in_n : std_logic;
++signal debug_aux : std_logic_vector(15 downto 0);
++
++-- CPU signals
++signal cpu_mode : std_logic_vector(1 downto 0);
++signal cpu_ready : std_logic;
++signal cpu_abort_n : std_logic;
++signal cpu_irq_n : std_logic;
++signal cpu_nmi_n : std_logic;
++signal cpu_so_n : std_logic;
++signal cpu_r_nw : std_logic;
++signal cpu_sync : std_logic;
++signal cpu_ef : std_logic;
++signal cpu_mf : std_logic;
++signal cpu_xf : std_logic;
++signal cpu_ml_n : std_logic;
++signal cpu_vp_n : std_logic;
++signal cpu_vda : std_logic;
++signal cpu_vpa : std_logic;
++signal cpu_a : std_logic_vector(23 downto 0);
++signal cpu_di : std_logic_vector(7 downto 0);
++signal cpu_do : std_logic_vector(7 downto 0);
++
++-- CRTC signals
++signal crtc_clken : std_logic;
++signal crtc_do : std_logic_vector(7 downto 0);
++signal crtc_vsync : std_logic;
++signal crtc_hsync : std_logic;
++signal crtc_de : std_logic;
++signal crtc_cursor : std_logic;
++signal crtc_lpstb : std_logic := '0';
++signal crtc_ma : std_logic_vector(13 downto 0);
++signal crtc_ra : std_logic_vector(4 downto 0);
++
++-- Decoded display address after address translation for hardware
++-- scrolling
++signal display_a : std_logic_vector(14 downto 0);
++
++-- "VIDPROC" signals
++signal vidproc_invert_n : std_logic;
++signal vidproc_disen : std_logic;
++signal r_in : std_logic;
++signal g_in : std_logic;
++signal b_in : std_logic;
++signal r_out : std_logic;
++signal g_out : std_logic;
++signal b_out : std_logic;
++
++-- SAA5050 signals
++signal ttxt_glr : std_logic;
++signal ttxt_dew : std_logic;
++signal ttxt_crs : std_logic;
++signal ttxt_lose : std_logic;
++signal ttxt_r : std_logic;
++signal ttxt_g : std_logic;
++signal ttxt_b : std_logic;
++signal ttxt_y : std_logic;
++
++-- System VIA signals
++signal sys_via_do : std_logic_vector(7 downto 0);
++signal sys_via_do_oe_n : std_logic;
++signal sys_via_irq_n : std_logic;
++signal sys_via_ca1_in : std_logic := '0';
++signal sys_via_ca2_in : std_logic := '0';
++signal sys_via_ca2_out : std_logic;
++signal sys_via_ca2_oe_n : std_logic;
++signal sys_via_pa_in : std_logic_vector(7 downto 0);
++signal sys_via_pa_out : std_logic_vector(7 downto 0);
++signal sys_via_pa_oe_n : std_logic_vector(7 downto 0);
++signal sys_via_cb1_in : std_logic := '0';
++signal sys_via_cb1_out : std_logic;
++signal sys_via_cb1_oe_n : std_logic;
++signal sys_via_cb2_in : std_logic := '0';
++signal sys_via_cb2_out : std_logic;
++signal sys_via_cb2_oe_n : std_logic;
++signal sys_via_pb_in : std_logic_vector(7 downto 0);
++signal sys_via_pb_out : std_logic_vector(7 downto 0);
++signal sys_via_pb_oe_n : std_logic_vector(7 downto 0);
++
++-- User VIA signals
++signal user_via_do : std_logic_vector(7 downto 0);
++signal user_via_do_oe_n : std_logic;
++signal user_via_irq_n : std_logic;
++signal user_via_ca1_in : std_logic := '0';
++signal user_via_ca2_in : std_logic := '0';
++signal user_via_ca2_out : std_logic;
++signal user_via_ca2_oe_n : std_logic;
++signal user_via_pa_in : std_logic_vector(7 downto 0);
++signal user_via_pa_out : std_logic_vector(7 downto 0);
++signal user_via_pa_oe_n : std_logic_vector(7 downto 0);
++signal user_via_cb1_in : std_logic := '0';
++signal user_via_cb1_out : std_logic;
++signal user_via_cb1_oe_n : std_logic;
++signal user_via_cb2_in : std_logic := '0';
++signal user_via_cb2_out : std_logic;
++signal user_via_cb2_oe_n : std_logic;
++signal user_via_pb_in : std_logic_vector(7 downto 0);
++signal user_via_pb_out : std_logic_vector(7 downto 0);
++signal user_via_pb_oe_n : std_logic_vector(7 downto 0);
++
++-- IC32 latch on System VIA
++signal ic32 : std_logic_vector(7 downto 0);
++signal sound_enable_n : std_logic;
++signal speech_read_n : std_logic;
++signal speech_write_n : std_logic;
++signal keyb_enable_n : std_logic;
++signal disp_addr_offs : std_logic_vector(1 downto 0);
++signal caps_lock_led_n : std_logic;
++signal shift_lock_led_n : std_logic;
++
++-- Keyboard
++signal keyb_column : std_logic_vector(3 downto 0);
++signal keyb_row : std_logic_vector(2 downto 0);
++signal keyb_out : std_logic;
++signal keyb_int : std_logic;
++signal keyb_break : std_logic;
++
++-- Sound generator
++signal sound_ready : std_logic;
++signal sound_di : std_logic_vector(7 downto 0);
++signal sound_ao : signed(7 downto 0);
++signal pcm_inl : std_logic_vector(15 downto 0);
++signal pcm_inr : std_logic_vector(15 downto 0);
++
++-- Memory enables
++signal ram_enable : std_logic; -- 0x0000
++signal rom_enable : std_logic; -- 0x8000 (BASIC/sideways ROMs)
++signal mos_enable : std_logic; -- 0xC000
++-- IO region enables
++signal io_fred : std_logic; -- 0xFC00 (1 MHz bus)
++signal io_jim : std_logic; -- 0xFD00 (1 MHz bus)
++signal io_sheila : std_logic; -- 0xFE00 (System peripherals)
++-- SHIELA
++signal crtc_enable : std_logic; -- 0xFE00-FE07
++signal acia_enable : std_logic; -- 0xFE08-FE0F
++signal serproc_enable : std_logic; -- 0xFE10-FE1F
++signal vidproc_enable : std_logic; -- 0xFE20-FE2F
++signal romsel_enable : std_logic; -- 0xFE30-FE3F
++signal sys_via_enable : std_logic; -- 0xFE40-FE5F
++signal user_via_enable : std_logic; -- 0xFE60-FE7F
++signal fddc_enable : std_logic; -- 0xFE80-FE9F
++signal adlc_enable : std_logic; -- 0xFEA0-FEBF (Econet)
++signal adc_enable : std_logic; -- 0xFEC0-FEDF
++signal tube_enable : std_logic; -- 0xFEE0-FEFF
++
++-- ROM select latch
++signal romsel : std_logic_vector(3 downto 0);
++
++signal mhz1_enable : std_logic; -- Set for access to any 1 MHz peripheral
++
++begin
++ -------------------------
++ -- COMPONENT INSTANCES
++ -------------------------
++
++ -- 32 MHz master clock
++ pll: pll32 port map (
++ pll_reset,
++ CLOCK_24(0),
++ clock,
++ pll_locked );
++
++ -- Hardware debugger block (single-step, breakpoints)
++ debug: debugger port map (
++ clock,
++ hard_reset_n,
++ cpu_clken,
++ cpu_debug_clken,
++ debug_irq_in_n,
++ cpu_irq_n,
++ cpu_a(15 downto 0), cpu_r_nw, cpu_sync,
++ debug_aux,
++ SW(8), -- RUN
++ KEY(3), -- STEP
++ KEY(2), -- MODE
++ KEY(1), -- DIGIT
++ KEY(0), -- SET
++ HEX3, HEX2, HEX1, HEX0,
++ LEDR(3), -- BREAKPOINT
++ LEDR(2) -- WATCHPOINT
++ );
++
++ -- 6502 CPU
++ cpu : T65 port map (
++ cpu_mode,
++ reset_n,
++ cpu_debug_clken,
++ clock,
++ cpu_ready,
++ cpu_abort_n,
++ cpu_irq_n,
++ cpu_nmi_n,
++ cpu_so_n,
++ cpu_r_nw,
++ cpu_sync,
++ cpu_ef,
++ cpu_mf,
++ cpu_xf,
++ cpu_ml_n,
++ cpu_vp_n,
++ cpu_vda,
++ cpu_vpa,
++ cpu_a,
++ cpu_di,
++ cpu_do );
++
++ crtc : mc6845 port map (
++ clock,
++ crtc_clken,
++ reset_n,
++ crtc_enable,
++ cpu_r_nw,
++ cpu_a(0),
++ cpu_do,
++ crtc_do,
++ crtc_vsync,
++ crtc_hsync,
++ crtc_de,
++ crtc_cursor,
++ crtc_lpstb,
++ crtc_ma,
++ crtc_ra );
++
++ video_ula : vidproc port map (
++ clock,
++ vid_clken,
++ reset_n,
++ crtc_clken,
++ vidproc_enable,
++ cpu_a(0),
++ cpu_do,
++ SRAM_DQ(7 downto 0),
++ vidproc_invert_n,
++ vidproc_disen,
++ crtc_cursor,
++ r_in, g_in, b_in,
++ r_out, g_out, b_out
++ );
++
++ teletext : saa5050 port map (
++ CLOCK_24(0), -- This runs at 6 MHz, which we can't derive from the 32 MHz clock
++ ttxt_clken,
++ reset_n,
++ clock, -- Data input is synchronised from the bus clock domain
++ vid_clken,
++ SRAM_DQ(6 downto 0),
++ ttxt_glr,
++ ttxt_dew,
++ ttxt_crs,
++ ttxt_lose,
++ ttxt_r, ttxt_g, ttxt_b, ttxt_y
++ );
++
++ -- System VIA
++ system_via : m6522 port map (
++ cpu_a(3 downto 0),
++ cpu_do,
++ sys_via_do,
++ sys_via_do_oe_n,
++ cpu_r_nw,
++ sys_via_enable,
++ '0', -- nCS2
++ sys_via_irq_n,
++ sys_via_ca1_in,
++ sys_via_ca2_in,
++ sys_via_ca2_out,
++ sys_via_ca2_oe_n,
++ sys_via_pa_in,
++ sys_via_pa_out,
++ sys_via_pa_oe_n,
++ sys_via_cb1_in,
++ sys_via_cb1_out,
++ sys_via_cb1_oe_n,
++ sys_via_cb2_in,
++ sys_via_cb2_out,
++ sys_via_cb2_oe_n,
++ sys_via_pb_in,
++ sys_via_pb_out,
++ sys_via_pb_oe_n,
++ mhz1_clken,
++ hard_reset_n, -- System VIA is reset by power on reset only
++ mhz4_clken,
++ clock
++ );
++
++ -- User VIA
++ user_via : m6522 port map (
++ cpu_a(3 downto 0),
++ cpu_do,
++ user_via_do,
++ user_via_do_oe_n,
++ cpu_r_nw,
++ user_via_enable,
++ '0', -- nCS2
++ user_via_irq_n,
++ user_via_ca1_in,
++ user_via_ca2_in,
++ user_via_ca2_out,
++ user_via_ca2_oe_n,
++ user_via_pa_in,
++ user_via_pa_out,
++ user_via_pa_oe_n,
++ user_via_cb1_in,
++ user_via_cb1_out,
++ user_via_cb1_oe_n,
++ user_via_cb2_in,
++ user_via_cb2_out,
++ user_via_cb2_oe_n,
++ user_via_pb_in,
++ user_via_pb_out,
++ user_via_pb_oe_n,
++ mhz1_clken,
++ reset_n,
++ mhz4_clken,
++ clock
++ );
++
++ -- Keyboard
++ keyb : keyboard port map (
++ clock, hard_reset_n, mhz1_clken,
++ PS2_CLK, PS2_DAT,
++ keyb_enable_n,
++ keyb_column,
++ keyb_row,
++ keyb_out,
++ keyb_int,
++ keyb_break,
++ SW(7 downto 0)
++ );
++
++ -- Sound generator (and drive logic for I2S codec)
++ sound : sn76489_top port map (
++ clock, mhz4_clken,
++ reset_n, '0', sound_enable_n,
++ sound_ready, sound_di,
++ sound_ao
++ );
++ i2s : i2s_intf port map (
++ CLOCK_24(0), reset_n,
++ pcm_inl, pcm_inr,
++ std_logic_vector(sound_ao) & "00000000",
++ std_logic_vector(sound_ao) & "00000000",
++ AUD_XCK, AUD_DACLRCK,
++ AUD_BCLK, AUD_DACDAT, AUD_ADCDAT
++ );
++ i2c : i2c_loader
++ generic map (
++ log2_divider => 7
++ )
++ port map (
++ clock, reset_n,
++ I2C_SCLK, I2C_SDAT,
++ LEDR(5), -- IS_DONE
++ LEDR(4) -- IS_ERROR
++ );
++
++ -- Asynchronous reset
++ -- PLL is reset by external reset switch
++ pll_reset <= not SW(9);
++ -- Keyboard and System VIA are reset by external reset switch or PLL being out of lock
++ hard_reset_n <= not (pll_reset or not pll_locked);
++ -- Rest of system is reset by all of the above plus the keyboard BREAK key
++ reset_n <= hard_reset_n and not keyb_break;
++
++ -- Clock enable generation - 32 MHz clock split into 32 cycles
++ -- CPU is on 0 and 16 (but can be masked by 1 MHz bus accesses)
++ -- Video is on all odd cycles (16 MHz)
++ -- 1 MHz cycles are on cycle 31 (1 MHz)
++ vid_clken <= clken_counter(0); -- 1,3,5...
++ mhz4_clken <= clken_counter(0) and clken_counter(1) and clken_counter(2); -- 7/15/23/31
++ mhz2_clken <= mhz4_clken and clken_counter(3); -- 15/31
++ mhz1_clken <= mhz2_clken and clken_counter(4); -- 31
++ cpu_cycle <= not (clken_counter(0) or clken_counter(1) or clken_counter(2) or clken_counter(3)); -- 0/16
++ cpu_clken <= cpu_cycle and not cpu_cycle_mask;
++
++ clk_gen: process(clock,reset_n)
++ begin
++ if reset_n = '0' then
++ clken_counter <= (others => '0');
++ elsif rising_edge(clock) then
++ clken_counter <= clken_counter + 1;
++ end if;
++ end process;
++
++ cycle_stretch: process(clock,reset_n)
++ begin
++ if reset_n = '0' then
++ cpu_cycle_mask <= '0';
++ elsif rising_edge(clock) and mhz2_clken = '1' then
++ if mhz1_enable = '1' and cpu_cycle_mask = '0' then
++ -- Block CPU cycles until 1 MHz cycle has completed
++ cpu_cycle_mask <= '1';
++ end if;
++ if mhz1_clken = '1' then
++ -- CPU can run again
++ -- FIXME: This may not be correct in terms of CPU cycles, but it
++ -- should work
++ cpu_cycle_mask <= '0';
++ end if;
++ end if;
++ end process;
++
++ ttxt_clk_gen: process(CLOCK_24(0),reset_n)
++ begin
++ if reset_n = '0' then
++ ttxt_clken_counter <= (others => '0');
++ elsif rising_edge(CLOCK_24(0)) then
++ ttxt_clken_counter <= ttxt_clken_counter + 1;
++ end if;
++ end process;
++
++ -- 6 MHz clock enable for SAA5050
++ ttxt_clken <= '1' when ttxt_clken_counter = 0 else '0';
++
++ -- CPU configuration and fixed signals
++ cpu_mode <= "00"; -- 6502
++ cpu_ready <= '1';
++ cpu_abort_n <= '1';
++ cpu_nmi_n <= '1';
++ cpu_so_n <= '1';
++
++ -- Address decoding
++ -- 0x0000 = 32 KB SRAM
++ -- 0x8000 = 16 KB BASIC/Sideways ROMs
++ -- 0xC000 = 16 KB MOS ROM
++ --
++ -- IO regions are mapped into a hole in the MOS. There are three regions:
++ -- 0xFC00 = FRED
++ -- 0xFD00 = JIM
++ -- 0xFE00 = SHEILA
++ ram_enable <= not cpu_a(15);
++ rom_enable <= cpu_a(15) and not cpu_a(14);
++ mos_enable <= cpu_a(15) and cpu_a(14) and not (io_fred or io_jim or io_sheila);
++ io_fred <= '1' when cpu_a(15 downto 8) = "11111100" else '0';
++ io_jim <= '1' when cpu_a(15 downto 8) = "11111101" else '0';
++ io_sheila <= '1' when cpu_a(15 downto 8) = "11111110" else '0';
++ -- The following IO regions are accessed at 1 MHz and hence will stall the
++ -- CPU accordingly
++ mhz1_enable <= io_fred or io_jim or
++ adc_enable or sys_via_enable or user_via_enable or
++ serproc_enable or acia_enable or crtc_enable;
++
++ -- SHEILA address demux
++ -- All the system peripherals are mapped into this page as follows:
++ -- 0xFE00 - 0xFE07 = MC6845 CRTC
++ -- 0xFE08 - 0xFE0F = MC6850 ACIA (Serial/Tape)
++ -- 0xFE10 - 0xFE1F = Serial ULA
++ -- 0xFE20 - 0xFE2F = Video ULA
++ -- 0xFE30 - 0xFE3F = Paged ROM select latch
++ -- 0xFE40 - 0xFE5F = System VIA (6522)
++ -- 0xFE60 - 0xFE7F = User VIA (6522)
++ -- 0xFE80 - 0xFE9F = 8271 Floppy disc controller
++ -- 0xFEA0 - 0xFEBF = 68B54 ADLC for Econet
++ -- 0xFEC0 - 0xFEDF = uPD7002 ADC
++ -- 0xFEE0 - 0xFEFF = Tube ULA
++ process(cpu_a,io_sheila)
++ begin
++ -- All regions normally de-selected
++ crtc_enable <= '0';
++ acia_enable <= '0';
++ serproc_enable <= '0';
++ vidproc_enable <= '0';
++ romsel_enable <= '0';
++ sys_via_enable <= '0';
++ user_via_enable <= '0';
++ fddc_enable <= '0';
++ adlc_enable <= '0';
++ adc_enable <= '0';
++ tube_enable <= '0';
++
++ if io_sheila = '1' then
++ case cpu_a(7 downto 5) is
++ when "000" =>
++ -- 0xFE00
++ if cpu_a(4) = '0' then
++ if cpu_a(3) = '0' then
++ -- 0xFE00
++ crtc_enable <= '1';
++ else
++ -- 0xFE08
++ acia_enable <= '1';
++ end if;
++ else
++ -- 0xFE10
++ serproc_enable <= '1';
++ end if;
++ when "001" =>
++ -- 0xFE20
++ if cpu_a(4) = '0' then
++ -- 0xFE20
++ vidproc_enable <= '1';
++ else
++ -- 0xFE30
++ romsel_enable <= '1';
++ end if;
++ when "010" => sys_via_enable <= '1'; -- 0xFE40
++ when "011" => user_via_enable <= '1'; -- 0xFE60
++ when "100" => fddc_enable <= '1'; -- 0xFE80
++ when "101" => adlc_enable <= '1'; -- 0xFEA0
++ when "110" => adc_enable <= '1'; -- 0xFEC0
++ when "111" => tube_enable <= '1'; -- 0xFEE0
++ when others =>
++ null;
++ end case;
++ end if;
++ end process;
++
++ -- CPU data bus mux and interrupts
++ cpu_di <=
++ SRAM_DQ(7 downto 0) when ram_enable = '1' else
++ FL_DQ when rom_enable = '1' else
++ FL_DQ when mos_enable = '1' else
++ crtc_do when crtc_enable = '1' else
++ "00000010" when acia_enable = '1' else
++ sys_via_do when sys_via_enable = '1' else
++ user_via_do when user_via_enable = '1' else
++ (others => '0'); -- un-decoded locations are pulled down by RP1
++ debug_irq_in_n <= sys_via_irq_n and user_via_irq_n; -- route IRQ through debugger
++ --cpu_irq_n <= sys_via_irq_n and user_via_irq_n;
++
++ -- ROMs are in external flash and split into 16K slots (since this also suits other
++ -- computers that might be run on the same board).
++ -- The first 8 slots are allocated for use here, and the first 4 are decoded as
++ -- the sideways ROMs. Slot 7 is used for the MOS.
++ FL_RST_N <= reset_n;
++ FL_CE_N <= '0';
++ FL_OE_N <= '0';
++ FL_WE_N <= '1';
++ FL_ADDR(21 downto 17) <= ROM_OFFSET(7 downto 3);
++ FL_ADDR(16 downto 14) <=
++ "111" when mos_enable = '1' else
++ "0" & romsel(1 downto 0);
++ FL_ADDR(13 downto 0) <= cpu_a(13 downto 0);
++
++ -- SRAM bus
++ SRAM_UB_N <= '1';
++ SRAM_LB_N <= '0';
++ SRAM_CE_N <= '0';
++ SRAM_OE_N <= '0';
++ SRAM_DQ(15 downto 8) <= (others => '0');
++
++ -- Synchronous outputs to SRAM
++ process(clock,reset_n)
++ variable ram_write : std_logic;
++ begin
++ ram_write := ram_enable and not cpu_r_nw;
++
++ if reset_n = '0' then
++ SRAM_WE_N <= '1';
++ SRAM_DQ(7 downto 0) <= (others => 'Z');
++ elsif rising_edge(clock) then
++ -- Default to inputs
++ SRAM_DQ(7 downto 0) <= (others => 'Z');
++
++ -- Register SRAM signals to outputs (clock must be at least 2x CPU clock)
++ if vid_clken = '1' then
++ -- Fetch data from previous CPU cycle
++ SRAM_WE_N <= not ram_write;
++ SRAM_ADDR <= "00" & cpu_a(15 downto 0);
++ if ram_write = '1' then
++ SRAM_DQ(7 downto 0) <= cpu_do;
++ end if;
++ else
++ -- Fetch data from previous display cycle
++ SRAM_WE_N <= '1';
++ SRAM_ADDR <= "000" & display_a;
++ end if;
++ end if;
++ end process;
++
++ -- Address translation logic for calculation of display address
++ process(crtc_ma,crtc_ra,disp_addr_offs)
++ variable aa : unsigned(3 downto 0);
++ begin
++ if crtc_ma(12) = '0' then
++ -- No adjustment
++ aa := unsigned(crtc_ma(11 downto 8));
++ else
++ -- Address adjusted according to screen mode to compensate for
++ -- wrap at 0x8000.
++ case disp_addr_offs is
++ when "00" =>
++ -- Mode 3 - restart at 0x4000
++ aa := unsigned(crtc_ma(11 downto 8)) + 8;
++ when "01" =>
++ -- Mode 6 - restart at 0x6000
++ aa := unsigned(crtc_ma(11 downto 8)) + 12;
++ when "10" =>
++ -- Mode 0,1,2 - restart at 0x3000
++ aa := unsigned(crtc_ma(11 downto 8)) + 6;
++ when "11" =>
++ -- Mode 4,5 - restart at 0x5800
++ aa := unsigned(crtc_ma(11 downto 8)) + 11;
++ when others =>
++ null;
++ end case;
++ end if;
++
++ if crtc_ma(13) = '0' then
++ -- HI RES
++ display_a <= std_logic_vector(aa(3 downto 0)) & crtc_ma(7 downto 0) & crtc_ra(2 downto 0);
++ else
++ -- TTX VDU
++ display_a <= std_logic(aa(3)) & "1111" & crtc_ma(9 downto 0);
++ end if;
++ end process;
++
++ -- VIDPROC
++ vidproc_invert_n <= '1';
++ vidproc_disen <= crtc_de and not crtc_ra(3); -- DISEN is masked off by RA(3) for MODEs 3 and 6
++ r_in <= ttxt_r;
++ g_in <= ttxt_g;
++ b_in <= ttxt_b;
++
++ -- SAA5050
++ ttxt_glr <= not crtc_hsync;
++ ttxt_dew <= crtc_vsync;
++ ttxt_crs <= not crtc_ra(0);
++ ttxt_lose <= crtc_de;
++
++ -- CRTC drives video out (CSYNC on HSYNC output, VSYNC high)
++ VGA_HS <= not (crtc_hsync xor crtc_vsync);
++ VGA_VS <= '1';
++ VGA_R <= r_out & r_out & r_out & r_out;
++ VGA_G <= g_out & g_out & g_out & g_out;
++ VGA_B <= b_out & b_out & b_out & b_out;
++
++ -- Connections to System VIA
++ -- ADC
++ sys_via_cb1_in <= '1'; -- /EOC
++ -- CRTC
++ sys_via_ca1_in <= crtc_vsync;
++ sys_via_cb2_in <= crtc_lpstb;
++ -- Keyboard
++ sys_via_ca2_in <= keyb_int;
++ sys_via_pa_in(7) <= keyb_out;
++ sys_via_pa_in(6 downto 0) <= sys_via_pa_out(6 downto 0); -- Must loop back output pins or keyboard won't work
++ keyb_column <= sys_via_pa_out(3 downto 0);
++ keyb_row <= sys_via_pa_out(6 downto 4);
++ -- Sound
++ sound_di <= sys_via_pa_out;
++ -- Others (idle until missing bits implemented)
++ sys_via_pb_in(7 downto 4) <= (others => '1');
++
++ -- Connections to User VIA (user port is output on green LEDs)
++ user_via_ca1_in <= '1'; -- Pulled up
++ --LEDG <= user_via_pb_out;
++
++ -- MMBEEB
++ user_via_cb1_in <= user_via_pb_out(1);
++ SD_SCLK <= user_via_pb_out(1); -- SCLK
++ SD_MOSI <= user_via_pb_out(0); -- SDO
++ SD_nCS <= '0'; -- CS
++ user_via_cb2_in <= SD_MISO; -- SDI
++ user_via_pb_in <= user_via_pb_out;
++
++ -- ROM select latch
++ process(clock,reset_n)
++ begin
++ if reset_n = '0' then
++ romsel <= (others => '0');
++ elsif rising_edge(clock) then
++ if romsel_enable = '1' and cpu_r_nw = '0' then
++ romsel <= cpu_do(3 downto 0);
++ end if;
++ end if;
++ end process;
++
++ -- IC32 latch
++ sound_enable_n <= ic32(0);
++ speech_write_n <= ic32(1);
++ speech_read_n <= ic32(2);
++ keyb_enable_n <= ic32(3);
++ disp_addr_offs <= ic32(5 downto 4);
++ caps_lock_led_n <= ic32(6);
++ shift_lock_led_n <= ic32(7);
++
++ process(clock,reset_n)
++ variable bit_num : integer;
++ begin
++ bit_num := to_integer(unsigned(sys_via_pb_out(2 downto 0)));
++
++ if reset_n = '0' then
++ ic32 <= (others => '0');
++ elsif rising_edge(clock) then
++ ic32(bit_num) <= sys_via_pb_out(3);
++ end if;
++ end process;
++
++ -- Keyboard LEDs
++ LEDR(0) <= not caps_lock_led_n;
++ LEDR(1) <= not shift_lock_led_n;
++
++ -----------------
++ -- DEBUG STUFF
++ -----------------
++
++ GPIO_0(0) <= not (crtc_hsync xor crtc_vsync);
++ GPIO_0(1) <= crtc_de;
++
++end architecture;
+diff --git a/bbc_micro_de1_tb.vhd b/bbc_micro_de1_tb.vhd
+index 82012ec..9197958 100644
+--- a/bbc_micro_de1_tb.vhd
++++ b/bbc_micro_de1_tb.vhd
+@@ -1,299 +1,299 @@
+--- BBC Micro for Altera DE1
+---
+--- Copyright (c) 2011 Mike Stirling
+---
+--- 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 agreement from the author.
+---
+--- * License is granted for non-commercial use only. A fee may not be charged
+--- for redistributions as source code or in synthesized/hardware form without
+--- specific prior written agreement from the author.
+---
+--- 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.
+---
+-
+-library IEEE;
+-use IEEE.STD_LOGIC_1164.ALL;
+-use IEEE.NUMERIC_STD.ALL;
+-
+-entity bbc_micro_tb is
+-end entity;
+-
+-architecture tb of bbc_micro_tb is
+-component bbc_micro_de1 is
+-port (
+- -- Clocks
+- CLOCK_24 : in std_logic_vector(1 downto 0);
+- CLOCK_27 : in std_logic_vector(1 downto 0);
+- CLOCK_50 : in std_logic;
+- EXT_CLOCK : in std_logic;
+-
+- -- Switches
+- SW : in std_logic_vector(9 downto 0);
+- -- Buttons
+- KEY : in std_logic_vector(3 downto 0);
+-
+- -- 7 segment displays
+- HEX0 : out std_logic_vector(6 downto 0);
+- HEX1 : out std_logic_vector(6 downto 0);
+- HEX2 : out std_logic_vector(6 downto 0);
+- HEX3 : out std_logic_vector(6 downto 0);
+- -- Red LEDs
+- LEDR : out std_logic_vector(9 downto 0);
+- -- Green LEDs
+- LEDG : out std_logic_vector(7 downto 0);
+-
+- -- VGA
+- VGA_R : out std_logic_vector(3 downto 0);
+- VGA_G : out std_logic_vector(3 downto 0);
+- VGA_B : out std_logic_vector(3 downto 0);
+- VGA_HS : out std_logic;
+- VGA_VS : out std_logic;
+-
+- -- Serial
+- UART_RXD : in std_logic;
+- UART_TXD : out std_logic;
+-
+- -- PS/2 Keyboard
+- PS2_CLK : inout std_logic;
+- PS2_DAT : inout std_logic;
+-
+- -- I2C
+- I2C_SCLK : inout std_logic;
+- I2C_SDAT : inout std_logic;
+-
+- -- Audio
+- AUD_XCK : out std_logic;
+- AUD_BCLK : out std_logic;
+- AUD_ADCLRCK : out std_logic;
+- AUD_ADCDAT : in std_logic;
+- AUD_DACLRCK : out std_logic;
+- AUD_DACDAT : out std_logic;
+-
+- -- SRAM
+- SRAM_ADDR : out std_logic_vector(17 downto 0);
+- SRAM_DQ : inout std_logic_vector(15 downto 0);
+- SRAM_CE_N : out std_logic;
+- SRAM_OE_N : out std_logic;
+- SRAM_WE_N : out std_logic;
+- SRAM_UB_N : out std_logic;
+- SRAM_LB_N : out std_logic;
+-
+- -- SDRAM
+- DRAM_ADDR : out std_logic_vector(11 downto 0);
+- DRAM_DQ : inout std_logic_vector(15 downto 0);
+- DRAM_BA_0 : in std_logic;
+- DRAM_BA_1 : in std_logic;
+- DRAM_CAS_N : in std_logic;
+- DRAM_CKE : in std_logic;
+- DRAM_CLK : in std_logic;
+- DRAM_CS_N : in std_logic;
+- DRAM_LDQM : in std_logic;
+- DRAM_RAS_N : in std_logic;
+- DRAM_UDQM : in std_logic;
+- DRAM_WE_N : in std_logic;
+-
+- -- Flash
+- FL_ADDR : out std_logic_vector(21 downto 0);
+- FL_DQ : inout std_logic_vector(7 downto 0);
+- FL_RST_N : in std_logic;
+- FL_OE_N : in std_logic;
+- FL_WE_N : in std_logic;
+-
+- -- GPIO
+- GPIO_0 : inout std_logic_vector(35 downto 0);
+- GPIO_1 : inout std_logic_vector(35 downto 0)
+- );
+-end component;
+-
+-
+-signal clock_24 : std_logic_vector(1 downto 0) := "00";
+-signal clock_27 : std_logic_vector(1 downto 0) := "00";
+-signal clock_50 : std_logic := '0';
+-signal ext_clock : std_logic := '0';
+-signal sw : std_logic_vector(9 downto 0);
+-signal key : std_logic_vector(3 downto 0);
+-signal hex0 : std_logic_vector(6 downto 0);
+-signal hex1 : std_logic_vector(6 downto 0);
+-signal hex2 : std_logic_vector(6 downto 0);
+-signal hex3 : std_logic_vector(6 downto 0);
+-signal ledr : std_logic_vector(9 downto 0);
+-signal ledg : std_logic_vector(7 downto 0);
+-signal vga_r : std_logic_vector(3 downto 0);
+-signal vga_g : std_logic_vector(3 downto 0);
+-signal vga_b : std_logic_vector(3 downto 0);
+-signal vga_hs : std_logic;
+-signal vga_vs : std_logic;
+-signal uart_rxd : std_logic;
+-signal uart_txd : std_logic;
+-signal ps2_clk : std_logic;
+-signal ps2_dat : std_logic;
+-signal i2c_sclk : std_logic;
+-signal i2c_sdat : std_logic;
+-signal aud_xck : std_logic;
+-signal aud_bclk : std_logic;
+-signal aud_adclrck : std_logic;
+-signal aud_adcdat : std_logic;
+-signal aud_daclrck : std_logic;
+-signal aud_dacdat : std_logic;
+-signal sram_addr : std_logic_vector(17 downto 0);
+-signal sram_dq : std_logic_vector(15 downto 0);
+-signal sram_ce_n : std_logic;
+-signal sram_oe_n : std_logic;
+-signal sram_we_n : std_logic;
+-signal sram_ub_n : std_logic;
+-signal sram_lb_n : std_logic;
+-signal dram_addr : std_logic_vector(11 downto 0);
+-signal dram_dq : std_logic_vector(15 downto 0);
+-signal dram_ba_0 : std_logic;
+-signal dram_ba_1 : std_logic;
+-signal dram_cas_n : std_logic;
+-signal dram_cke : std_logic;
+-signal dram_clk : std_logic;
+-signal dram_cs_n : std_logic;
+-signal dram_ldqm : std_logic;
+-signal dram_ras_n : std_logic;
+-signal dram_udqm : std_logic;
+-signal dram_we_n : std_logic;
+-signal fl_addr : std_logic_vector(21 downto 0);
+-signal fl_dq : std_logic_vector(7 downto 0);
+-signal fl_rst_n : std_logic;
+-signal fl_oe_n : std_logic;
+-signal fl_we_n : std_logic;
+-signal gpio_0 : std_logic_vector(35 downto 0);
+-signal gpio_1 : std_logic_vector(35 downto 0);
+-
+-signal n_reset : std_logic := '0';
+-signal n_slow : std_logic := '1';
+-
+-type ram_t is array(0 to 65535) of std_logic_vector(15 downto 0);
+-signal ram : ram_t;
+-signal ram_a : std_logic_vector(15 downto 0);
+-begin
+-
+- uut: bbc_micro_de1 port map (
+- clock_24,
+- clock_27,
+- clock_50,
+- ext_clock,
+- sw,
+- key,
+- hex0,
+- hex1,
+- hex2,
+- hex3,
+- ledr,
+- ledg,
+- vga_r,
+- vga_g,
+- vga_b,
+- vga_hs,
+- vga_vs,
+- uart_rxd,
+- uart_txd,
+- ps2_clk,
+- ps2_dat,
+- i2c_sclk,
+- i2c_sdat,
+- aud_xck,
+- aud_bclk,
+- aud_adclrck,
+- aud_adcdat,
+- aud_daclrck,
+- aud_dacdat,
+- sram_addr,
+- sram_dq,
+- sram_ce_n,
+- sram_oe_n,
+- sram_we_n,
+- sram_ub_n,
+- sram_lb_n,
+- dram_addr,
+- dram_dq,
+- dram_ba_0,
+- dram_ba_1,
+- dram_cas_n,
+- dram_cke,
+- dram_clk,
+- dram_cs_n,
+- dram_ldqm,
+- dram_ras_n,
+- dram_udqm,
+- dram_we_n,
+- fl_addr,
+- fl_dq,
+- fl_rst_n,
+- fl_oe_n,
+- fl_we_n,
+- gpio_0,
+- gpio_1
+- );
+-
+- sw <= n_reset & n_slow & "00000101";
+- clock_50 <= not clock_50 after 10 ns;
+- clock_27(0) <= not clock_27(0) after 18.5 ns;
+- clock_27(1) <= not clock_27(1) after 18.5 ns;
+- clock_24(0) <= not clock_24(0) after 20.8 ns;
+- clock_24(1) <= not clock_24(1) after 20.8 ns;
+-
+- reset: process
+- begin
+- wait for 100 ns;
+- n_reset <= '1';
+- end process;
+-
+- sram: process(sram_addr,sram_dq,sram_ce_n,sram_oe_n,sram_we_n,sram_ub_n,sram_lb_n)
+- begin
+- if sram_ce_n = '0' then
+- if sram_oe_n = '0' and sram_we_n = '1' then
+- if sram_ub_n = '0' then
+- sram_dq(15 downto 8) <= ram(to_integer(unsigned(sram_addr(15 downto 0))))(15 downto 8);
+- else
+- sram_dq(15 downto 8) <= (others => 'Z');
+- end if;
+- if sram_lb_n = '0' then
+- sram_dq(7 downto 0) <= ram(to_integer(unsigned(sram_addr(15 downto 0))))(7 downto 0);
+- else
+- sram_dq(7 downto 0) <= (others => 'Z');
+- end if;
+- else
+- sram_dq(15 downto 0) <= (others => 'Z');
+- if sram_we_n = '0' then
+- if sram_ub_n = '0' then
+- ram(to_integer(unsigned(sram_addr(15 downto 0))))(15 downto 8) <= sram_dq(15 downto 8);
+- end if;
+- if sram_lb_n = '0' then
+- ram(to_integer(unsigned(sram_addr(15 downto 0))))(7 downto 0) <= sram_dq(7 downto 0);
+- end if;
+- end if;
+- end if;
+- else
+- sram_dq <= (others => 'Z');
+- end if;
+- end process;
+-
+-
+-end architecture;
++-- BBC Micro for Altera DE1
++--
++-- Copyright (c) 2011 Mike Stirling
++--
++-- 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 agreement from the author.
++--
++-- * License is granted for non-commercial use only. A fee may not be charged
++-- for redistributions as source code or in synthesized/hardware form without
++-- specific prior written agreement from the author.
++--
++-- 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.
++--
++
++library IEEE;
++use IEEE.STD_LOGIC_1164.ALL;
++use IEEE.NUMERIC_STD.ALL;
++
++entity bbc_micro_tb is
++end entity;
++
++architecture tb of bbc_micro_tb is
++component bbc_micro_de1 is
++port (
++ -- Clocks
++ CLOCK_24 : in std_logic_vector(1 downto 0);
++ CLOCK_27 : in std_logic_vector(1 downto 0);
++ CLOCK_50 : in std_logic;
++ EXT_CLOCK : in std_logic;
++
++ -- Switches
++ SW : in std_logic_vector(9 downto 0);
++ -- Buttons
++ KEY : in std_logic_vector(3 downto 0);
++
++ -- 7 segment displays
++ HEX0 : out std_logic_vector(6 downto 0);
++ HEX1 : out std_logic_vector(6 downto 0);
++ HEX2 : out std_logic_vector(6 downto 0);
++ HEX3 : out std_logic_vector(6 downto 0);
++ -- Red LEDs
++ LEDR : out std_logic_vector(9 downto 0);
++ -- Green LEDs
++ LEDG : out std_logic_vector(7 downto 0);
++
++ -- VGA
++ VGA_R : out std_logic_vector(3 downto 0);
++ VGA_G : out std_logic_vector(3 downto 0);
++ VGA_B : out std_logic_vector(3 downto 0);
++ VGA_HS : out std_logic;
++ VGA_VS : out std_logic;
++
++ -- Serial
++ UART_RXD : in std_logic;
++ UART_TXD : out std_logic;
++
++ -- PS/2 Keyboard
++ PS2_CLK : inout std_logic;
++ PS2_DAT : inout std_logic;
++
++ -- I2C
++ I2C_SCLK : inout std_logic;
++ I2C_SDAT : inout std_logic;
++
++ -- Audio
++ AUD_XCK : out std_logic;
++ AUD_BCLK : out std_logic;
++ AUD_ADCLRCK : out std_logic;
++ AUD_ADCDAT : in std_logic;
++ AUD_DACLRCK : out std_logic;
++ AUD_DACDAT : out std_logic;
++
++ -- SRAM
++ SRAM_ADDR : out std_logic_vector(17 downto 0);
++ SRAM_DQ : inout std_logic_vector(15 downto 0);
++ SRAM_CE_N : out std_logic;
++ SRAM_OE_N : out std_logic;
++ SRAM_WE_N : out std_logic;
++ SRAM_UB_N : out std_logic;
++ SRAM_LB_N : out std_logic;
++
++ -- SDRAM
++ DRAM_ADDR : out std_logic_vector(11 downto 0);
++ DRAM_DQ : inout std_logic_vector(15 downto 0);
++ DRAM_BA_0 : in std_logic;
++ DRAM_BA_1 : in std_logic;
++ DRAM_CAS_N : in std_logic;
++ DRAM_CKE : in std_logic;
++ DRAM_CLK : in std_logic;
++ DRAM_CS_N : in std_logic;
++ DRAM_LDQM : in std_logic;
++ DRAM_RAS_N : in std_logic;
++ DRAM_UDQM : in std_logic;
++ DRAM_WE_N : in std_logic;
++
++ -- Flash
++ FL_ADDR : out std_logic_vector(21 downto 0);
++ FL_DQ : inout std_logic_vector(7 downto 0);
++ FL_RST_N : in std_logic;
++ FL_OE_N : in std_logic;
++ FL_WE_N : in std_logic;
++
++ -- GPIO
++ GPIO_0 : inout std_logic_vector(35 downto 0);
++ GPIO_1 : inout std_logic_vector(35 downto 0)
++ );
++end component;
++
++
++signal clock_24 : std_logic_vector(1 downto 0) := "00";
++signal clock_27 : std_logic_vector(1 downto 0) := "00";
++signal clock_50 : std_logic := '0';
++signal ext_clock : std_logic := '0';
++signal sw : std_logic_vector(9 downto 0);
++signal key : std_logic_vector(3 downto 0);
++signal hex0 : std_logic_vector(6 downto 0);
++signal hex1 : std_logic_vector(6 downto 0);
++signal hex2 : std_logic_vector(6 downto 0);
++signal hex3 : std_logic_vector(6 downto 0);
++signal ledr : std_logic_vector(9 downto 0);
++signal ledg : std_logic_vector(7 downto 0);
++signal vga_r : std_logic_vector(3 downto 0);
++signal vga_g : std_logic_vector(3 downto 0);
++signal vga_b : std_logic_vector(3 downto 0);
++signal vga_hs : std_logic;
++signal vga_vs : std_logic;
++signal uart_rxd : std_logic;
++signal uart_txd : std_logic;
++signal ps2_clk : std_logic;
++signal ps2_dat : std_logic;
++signal i2c_sclk : std_logic;
++signal i2c_sdat : std_logic;
++signal aud_xck : std_logic;
++signal aud_bclk : std_logic;
++signal aud_adclrck : std_logic;
++signal aud_adcdat : std_logic;
++signal aud_daclrck : std_logic;
++signal aud_dacdat : std_logic;
++signal sram_addr : std_logic_vector(17 downto 0);
++signal sram_dq : std_logic_vector(15 downto 0);
++signal sram_ce_n : std_logic;
++signal sram_oe_n : std_logic;
++signal sram_we_n : std_logic;
++signal sram_ub_n : std_logic;
++signal sram_lb_n : std_logic;
++signal dram_addr : std_logic_vector(11 downto 0);
++signal dram_dq : std_logic_vector(15 downto 0);
++signal dram_ba_0 : std_logic;
++signal dram_ba_1 : std_logic;
++signal dram_cas_n : std_logic;
++signal dram_cke : std_logic;
++signal dram_clk : std_logic;
++signal dram_cs_n : std_logic;
++signal dram_ldqm : std_logic;
++signal dram_ras_n : std_logic;
++signal dram_udqm : std_logic;
++signal dram_we_n : std_logic;
++signal fl_addr : std_logic_vector(21 downto 0);
++signal fl_dq : std_logic_vector(7 downto 0);
++signal fl_rst_n : std_logic;
++signal fl_oe_n : std_logic;
++signal fl_we_n : std_logic;
++signal gpio_0 : std_logic_vector(35 downto 0);
++signal gpio_1 : std_logic_vector(35 downto 0);
++
++signal n_reset : std_logic := '0';
++signal n_slow : std_logic := '1';
++
++type ram_t is array(0 to 65535) of std_logic_vector(15 downto 0);
++signal ram : ram_t;
++signal ram_a : std_logic_vector(15 downto 0);
++begin
++
++ uut: bbc_micro_de1 port map (
++ clock_24,
++ clock_27,
++ clock_50,
++ ext_clock,
++ sw,
++ key,
++ hex0,
++ hex1,
++ hex2,
++ hex3,
++ ledr,
++ ledg,
++ vga_r,
++ vga_g,
++ vga_b,
++ vga_hs,
++ vga_vs,
++ uart_rxd,
++ uart_txd,
++ ps2_clk,
++ ps2_dat,
++ i2c_sclk,
++ i2c_sdat,
++ aud_xck,
++ aud_bclk,
++ aud_adclrck,
++ aud_adcdat,
++ aud_daclrck,
++ aud_dacdat,
++ sram_addr,
++ sram_dq,
++ sram_ce_n,
++ sram_oe_n,
++ sram_we_n,
++ sram_ub_n,
++ sram_lb_n,
++ dram_addr,
++ dram_dq,
++ dram_ba_0,
++ dram_ba_1,
++ dram_cas_n,
++ dram_cke,
++ dram_clk,
++ dram_cs_n,
++ dram_ldqm,
++ dram_ras_n,
++ dram_udqm,
++ dram_we_n,
++ fl_addr,
++ fl_dq,
++ fl_rst_n,
++ fl_oe_n,
++ fl_we_n,
++ gpio_0,
++ gpio_1
++ );
++
++ sw <= n_reset & n_slow & "00000101";
++ clock_50 <= not clock_50 after 10 ns;
++ clock_27(0) <= not clock_27(0) after 18.5 ns;
++ clock_27(1) <= not clock_27(1) after 18.5 ns;
++ clock_24(0) <= not clock_24(0) after 20.8 ns;
++ clock_24(1) <= not clock_24(1) after 20.8 ns;
++
++ reset: process
++ begin
++ wait for 100 ns;
++ n_reset <= '1';
++ end process;
++
++ sram: process(sram_addr,sram_dq,sram_ce_n,sram_oe_n,sram_we_n,sram_ub_n,sram_lb_n)
++ begin
++ if sram_ce_n = '0' then
++ if sram_oe_n = '0' and sram_we_n = '1' then
++ if sram_ub_n = '0' then
++ sram_dq(15 downto 8) <= ram(to_integer(unsigned(sram_addr(15 downto 0))))(15 downto 8);
++ else
++ sram_dq(15 downto 8) <= (others => 'Z');
++ end if;
++ if sram_lb_n = '0' then
++ sram_dq(7 downto 0) <= ram(to_integer(unsigned(sram_addr(15 downto 0))))(7 downto 0);
++ else
++ sram_dq(7 downto 0) <= (others => 'Z');
++ end if;
++ else
++ sram_dq(15 downto 0) <= (others => 'Z');
++ if sram_we_n = '0' then
++ if sram_ub_n = '0' then
++ ram(to_integer(unsigned(sram_addr(15 downto 0))))(15 downto 8) <= sram_dq(15 downto 8);
++ end if;
++ if sram_lb_n = '0' then
++ ram(to_integer(unsigned(sram_addr(15 downto 0))))(7 downto 0) <= sram_dq(7 downto 0);
++ end if;
++ end if;
++ end if;
++ else
++ sram_dq <= (others => 'Z');
++ end if;
++ end process;
++
++
++end architecture;
+diff --git a/debugger.vhd b/debugger.vhd
+index 1d78bd5..a7a9d7d 100644
+--- a/debugger.vhd
++++ b/debugger.vhd
+@@ -1,300 +1,300 @@
+--- BBC Micro for Altera DE1
+---
+--- Copyright (c) 2011 Mike Stirling
+---
+--- 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 agreement from the author.
+---
+--- * License is granted for non-commercial use only. A fee may not be charged
+--- for redistributions as source code or in synthesized/hardware form without
+--- specific prior written agreement from the author.
+---
+--- 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.
+---
+---
+--- General purpose hardware debugger
+---
+--- (C) 2011 Mike Stirling
+---
+-
+-library IEEE;
+-use IEEE.STD_LOGIC_1164.ALL;
+-use IEEE.NUMERIC_STD.ALL;
+-
+-entity debugger is
+-generic (
+- -- Set this for a reasonable half flash duration relative to the
+- -- clock frequency
+- flash_divider : natural := 24
+- );
+-port (
+- CLOCK : in std_logic;
+- nRESET : in std_logic;
+- -- CPU clock enable in
+- CLKEN_IN : in std_logic;
+- -- Gated clock enable back out to CPU
+- CLKEN_OUT : out std_logic;
+- -- CPU IRQ in
+- nIRQ_IN : in std_logic;
+- -- Gated IRQ back out to CPU (no interrupts when single stepping)
+- nIRQ_OUT : out std_logic;
+-
+- -- CPU
+- A_CPU : in std_logic_vector(15 downto 0);
+- R_nW : in std_logic;
+- SYNC : in std_logic;
+-
+- -- Aux bus input for display in hex
+- AUX_BUS : in std_logic_vector(15 downto 0);
+-
+- -- Controls
+- -- RUN or HALT CPU
+- RUN : in std_logic;
+- -- Push button to single-step in HALT mode
+- nSTEP : in std_logic;
+- -- Push button to cycle display mode
+- nMODE : in std_logic;
+- -- Push button to cycle display digit in edit mode
+- nDIGIT : in std_logic;
+- -- Push button to cycle digit value in edit mode
+- nSET : in std_logic;
+-
+- -- Output to display
+- DIGIT3 : out std_logic_vector(6 downto 0);
+- DIGIT2 : out std_logic_vector(6 downto 0);
+- DIGIT1 : out std_logic_vector(6 downto 0);
+- DIGIT0 : out std_logic_vector(6 downto 0);
+-
+- LED_BREAKPOINT : out std_logic;
+- LED_WATCHPOINT : out std_logic
+- );
+-end entity;
+-
+-architecture rtl of debugger is
+-
+-component seg7 is
+-port (
+- D : in std_logic_vector(3 downto 0);
+- Q : out std_logic_vector(6 downto 0)
+-);
+-end component;
+-
+--- Current display mode
+-type mode_t is (modeAddress,modeBreak,modeWatch,modeAux);
+-signal mode : mode_t;
+--- Current edit digit
+-signal digit : unsigned(1 downto 0);
+--- For flashing selected digit
+-signal counter : unsigned(flash_divider-1 downto 0);
+-signal flash : std_logic;
+--- Selected breakpoint address (stop on instruction fetch)
+-signal breakpoint : std_logic_vector(15 downto 0);
+--- Selected watchpoint address (stop on write)
+-signal watchpoint : std_logic_vector(15 downto 0);
+--- Address of last instruction fetch
+-signal instr_addr : std_logic_vector(15 downto 0);
+--- Break flags
+-signal halt : std_logic;
+--- Set when a request to resume has been received but before
+--- the CPU has run
+-signal resuming : std_logic;
+-
+--- Display interface
+-signal a_display : std_logic_vector(15 downto 0);
+-signal d3_display : std_logic_vector(6 downto 0);
+-signal d2_display : std_logic_vector(6 downto 0);
+-signal d1_display : std_logic_vector(6 downto 0);
+-signal d0_display : std_logic_vector(6 downto 0);
+-
+--- Registered button inputs
+-signal r_step_n : std_logic;
+-signal r_mode_n : std_logic;
+-signal r_digit_n : std_logic;
+-signal r_set_n : std_logic;
+-
+-begin
+- -- Mask CPU clock enable
+- CLKEN_OUT <= CLKEN_IN and not halt;
+- -- Mask interrupt
+- nIRQ_OUT <= nIRQ_IN or not RUN;
+-
+- -- Route selected address to display
+- a_display <= instr_addr when mode = modeAddress else
+- breakpoint when mode = modeBreak else
+- watchpoint when mode = modeWatch else
+- AUX_BUS when mode = modeAux else
+- (others => '0');
+-
+- -- Generate display digits from binary
+- d3 : seg7 port map (a_display(15 downto 12),d3_display);
+- d2 : seg7 port map (a_display(11 downto 8),d2_display);
+- d1 : seg7 port map (a_display(7 downto 4),d1_display);
+- d0 : seg7 port map (a_display(3 downto 0),d0_display);
+-
+- -- Flash selected digit in edit modes
+- DIGIT3 <= d3_display when (mode = modeAddress or mode = modeAux or flash = '1' or digit /= "11") else "1111111";
+- DIGIT2 <= d2_display when (mode = modeAddress or mode = modeAux or flash = '1' or digit /= "10") else "1111111";
+- DIGIT1 <= d1_display when (mode = modeAddress or mode = modeAux or flash = '1' or digit /= "01") else "1111111";
+- DIGIT0 <= d0_display when (mode = modeAddress or mode = modeAux or flash = '1' or digit /= "00") else "1111111";
+-
+- -- Show mode on LEDs
+- LED_BREAKPOINT <= '1' when mode = modeBreak or mode = modeAux else '0';
+- LED_WATCHPOINT <= '1' when mode = modeWatch or mode = modeAux else '0';
+-
+- -- Flash counter
+- process(CLOCK,nRESET)
+- begin
+- if nRESET = '0' then
+- counter <= (others => '0');
+- flash <= '0';
+- elsif rising_edge(CLOCK) then
+- counter <= counter + 1;
+- if counter = 0 then
+- flash <= not flash;
+- end if;
+- end if;
+- end process;
+-
+- -- Register buttons, select input mode and digit
+- process(CLOCK,nRESET)
+- begin
+- if nRESET = '0' then
+- r_mode_n <= '1';
+- r_digit_n <= '1';
+- r_set_n <= '1';
+- mode <= modeAddress;
+- digit <= (others => '0');
+- elsif rising_edge(CLOCK) then
+- -- Register buttons
+- r_mode_n <= nMODE;
+- r_digit_n <= nDIGIT;
+- r_set_n <= nSET;
+-
+- if r_mode_n = '1' and nMODE = '0' then
+- -- Increment mode
+- if mode = modeAddress then
+- mode <= modeBreak;
+- elsif mode = modeBreak then
+- mode <= modeWatch;
+- elsif mode = modeWatch then
+- mode <= modeAux;
+- else
+- mode <= modeAddress;
+- end if;
+- end if;
+- if r_digit_n = '1' and nDIGIT = '0' then
+- -- Increment digit
+- digit <= digit + 1;
+- end if;
+- end if;
+- end process;
+-
+- -- Set watchpoint address
+- process(CLOCK,nRESET)
+- begin
+- if nRESET = '0' then
+- watchpoint <= (others => '1');
+- elsif rising_edge(CLOCK) and mode = modeWatch then
+- if r_set_n = '1' and nSET = '0' then
+- -- Increment selected digit on each button press
+- case digit is
+- when "00" => watchpoint(3 downto 0) <= std_logic_vector(unsigned(watchpoint(3 downto 0)) + 1);
+- when "01" => watchpoint(7 downto 4) <= std_logic_vector(unsigned(watchpoint(7 downto 4)) + 1);
+- when "10" => watchpoint(11 downto 8) <= std_logic_vector(unsigned(watchpoint(11 downto 8)) + 1);
+- when "11" => watchpoint(15 downto 12) <= std_logic_vector(unsigned(watchpoint(15 downto 12)) + 1);
+- when others => null;
+- end case;
+- end if;
+- end if;
+- end process;
+-
+- -- Set breakpoint address
+- process(CLOCK,nRESET)
+- begin
+- if nRESET = '0' then
+- breakpoint <= (others => '1');
+- elsif rising_edge(CLOCK) and mode = modeBreak then
+- if r_set_n = '1' and nSET = '0' then
+- -- Increment selected digit on each button press
+- case digit is
+- when "00" => breakpoint(3 downto 0) <= std_logic_vector(unsigned(breakpoint(3 downto 0)) + 1);
+- when "01" => breakpoint(7 downto 4) <= std_logic_vector(unsigned(breakpoint(7 downto 4)) + 1);
+- when "10" => breakpoint(11 downto 8) <= std_logic_vector(unsigned(breakpoint(11 downto 8)) + 1);
+- when "11" => breakpoint(15 downto 12) <= std_logic_vector(unsigned(breakpoint(15 downto 12)) + 1);
+-
+- when others => null;
+- end case;
+- end if;
+- end if;
+- end process;
+-
+- -- CPU control logic
+- process(CLOCK,nRESET)
+- begin
+- if nRESET = '0' then
+- r_step_n <= '1';
+- halt <= '0';
+- resuming <= '0';
+- instr_addr <= (others => '0');
+- elsif rising_edge(CLOCK) then
+- -- Register single-step button
+- r_step_n <= nSTEP;
+-
+- -- Once the CPU has run we can trigger a new halt
+- if CLKEN_IN = '1' then
+- resuming <= '0';
+- end if;
+-
+- if SYNC = '1' then
+- -- Latch address of instruction fetch
+- instr_addr <= A_CPU;
+- end if;
+-
+- -- Check for halt conditions if we are not resuming from a previous halt
+- if resuming = '0' then
+- if RUN = '0' and SYNC = '1' then
+- -- If not in RUN mode then halt on any instruction fetch
+- -- (single-step)
+- halt <= '1';
+- end if;
+- if A_CPU = breakpoint and SYNC = '1' then
+- -- Halt CPU when instruction fetched from breakpoint address
+- halt <= '1';
+- end if;
+- if A_CPU = watchpoint and SYNC = '0' and R_nW = '0' then
+- -- Halt CPU when data write to watchpoint address
+- halt <= '1';
+- end if;
+- end if;
+-
+- -- Resume or single step when user presses "STEP" button
+- if r_step_n = '1' and nSTEP = '0' then
+- resuming <= '1';
+- halt <= '0';
+- end if;
+- end if;
+- end process;
+-end architecture;
++-- BBC Micro for Altera DE1
++--
++-- Copyright (c) 2011 Mike Stirling
++--
++-- 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 agreement from the author.
++--
++-- * License is granted for non-commercial use only. A fee may not be charged
++-- for redistributions as source code or in synthesized/hardware form without
++-- specific prior written agreement from the author.
++--
++-- 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.
++--
++--
++-- General purpose hardware debugger
++--
++-- (C) 2011 Mike Stirling
++--
++
++library IEEE;
++use IEEE.STD_LOGIC_1164.ALL;
++use IEEE.NUMERIC_STD.ALL;
++
++entity debugger is
++generic (
++ -- Set this for a reasonable half flash duration relative to the
++ -- clock frequency
++ flash_divider : natural := 24
++ );
++port (
++ CLOCK : in std_logic;
++ nRESET : in std_logic;
++ -- CPU clock enable in
++ CLKEN_IN : in std_logic;
++ -- Gated clock enable back out to CPU
++ CLKEN_OUT : out std_logic;
++ -- CPU IRQ in
++ nIRQ_IN : in std_logic;
++ -- Gated IRQ back out to CPU (no interrupts when single stepping)
++ nIRQ_OUT : out std_logic;
++
++ -- CPU
++ A_CPU : in std_logic_vector(15 downto 0);
++ R_nW : in std_logic;
++ SYNC : in std_logic;
++
++ -- Aux bus input for display in hex
++ AUX_BUS : in std_logic_vector(15 downto 0);
++
++ -- Controls
++ -- RUN or HALT CPU
++ RUN : in std_logic;
++ -- Push button to single-step in HALT mode
++ nSTEP : in std_logic;
++ -- Push button to cycle display mode
++ nMODE : in std_logic;
++ -- Push button to cycle display digit in edit mode
++ nDIGIT : in std_logic;
++ -- Push button to cycle digit value in edit mode
++ nSET : in std_logic;
++
++ -- Output to display
++ DIGIT3 : out std_logic_vector(6 downto 0);
++ DIGIT2 : out std_logic_vector(6 downto 0);
++ DIGIT1 : out std_logic_vector(6 downto 0);
++ DIGIT0 : out std_logic_vector(6 downto 0);
++
++ LED_BREAKPOINT : out std_logic;
++ LED_WATCHPOINT : out std_logic
++ );
++end entity;
++
++architecture rtl of debugger is
++
++component seg7 is
++port (
++ D : in std_logic_vector(3 downto 0);
++ Q : out std_logic_vector(6 downto 0)
++);
++end component;
++
++-- Current display mode
++type mode_t is (modeAddress,modeBreak,modeWatch,modeAux);
++signal mode : mode_t;
++-- Current edit digit
++signal digit : unsigned(1 downto 0);
++-- For flashing selected digit
++signal counter : unsigned(flash_divider-1 downto 0);
++signal flash : std_logic;
++-- Selected breakpoint address (stop on instruction fetch)
++signal breakpoint : std_logic_vector(15 downto 0);
++-- Selected watchpoint address (stop on write)
++signal watchpoint : std_logic_vector(15 downto 0);
++-- Address of last instruction fetch
++signal instr_addr : std_logic_vector(15 downto 0);
++-- Break flags
++signal halt : std_logic;
++-- Set when a request to resume has been received but before
++-- the CPU has run
++signal resuming : std_logic;
++
++-- Display interface
++signal a_display : std_logic_vector(15 downto 0);
++signal d3_display : std_logic_vector(6 downto 0);
++signal d2_display : std_logic_vector(6 downto 0);
++signal d1_display : std_logic_vector(6 downto 0);
++signal d0_display : std_logic_vector(6 downto 0);
++
++-- Registered button inputs
++signal r_step_n : std_logic;
++signal r_mode_n : std_logic;
++signal r_digit_n : std_logic;
++signal r_set_n : std_logic;
++
++begin
++ -- Mask CPU clock enable
++ CLKEN_OUT <= CLKEN_IN and not halt;
++ -- Mask interrupt
++ nIRQ_OUT <= nIRQ_IN or not RUN;
++
++ -- Route selected address to display
++ a_display <= instr_addr when mode = modeAddress else
++ breakpoint when mode = modeBreak else
++ watchpoint when mode = modeWatch else
++ AUX_BUS when mode = modeAux else
++ (others => '0');
++
++ -- Generate display digits from binary
++ d3 : seg7 port map (a_display(15 downto 12),d3_display);
++ d2 : seg7 port map (a_display(11 downto 8),d2_display);
++ d1 : seg7 port map (a_display(7 downto 4),d1_display);
++ d0 : seg7 port map (a_display(3 downto 0),d0_display);
++
++ -- Flash selected digit in edit modes
++ DIGIT3 <= d3_display when (mode = modeAddress or mode = modeAux or flash = '1' or digit /= "11") else "1111111";
++ DIGIT2 <= d2_display when (mode = modeAddress or mode = modeAux or flash = '1' or digit /= "10") else "1111111";
++ DIGIT1 <= d1_display when (mode = modeAddress or mode = modeAux or flash = '1' or digit /= "01") else "1111111";
++ DIGIT0 <= d0_display when (mode = modeAddress or mode = modeAux or flash = '1' or digit /= "00") else "1111111";
++
++ -- Show mode on LEDs
++ LED_BREAKPOINT <= '1' when mode = modeBreak or mode = modeAux else '0';
++ LED_WATCHPOINT <= '1' when mode = modeWatch or mode = modeAux else '0';
++
++ -- Flash counter
++ process(CLOCK,nRESET)
++ begin
++ if nRESET = '0' then
++ counter <= (others => '0');
++ flash <= '0';
++ elsif rising_edge(CLOCK) then
++ counter <= counter + 1;
++ if counter = 0 then
++ flash <= not flash;
++ end if;
++ end if;
++ end process;
++
++ -- Register buttons, select input mode and digit
++ process(CLOCK,nRESET)
++ begin
++ if nRESET = '0' then
++ r_mode_n <= '1';
++ r_digit_n <= '1';
++ r_set_n <= '1';
++ mode <= modeAddress;
++ digit <= (others => '0');
++ elsif rising_edge(CLOCK) then
++ -- Register buttons
++ r_mode_n <= nMODE;
++ r_digit_n <= nDIGIT;
++ r_set_n <= nSET;
++
++ if r_mode_n = '1' and nMODE = '0' then
++ -- Increment mode
++ if mode = modeAddress then
++ mode <= modeBreak;
++ elsif mode = modeBreak then
++ mode <= modeWatch;
++ elsif mode = modeWatch then
++ mode <= modeAux;
++ else
++ mode <= modeAddress;
++ end if;
++ end if;
++ if r_digit_n = '1' and nDIGIT = '0' then
++ -- Increment digit
++ digit <= digit + 1;
++ end if;
++ end if;
++ end process;
++
++ -- Set watchpoint address
++ process(CLOCK,nRESET)
++ begin
++ if nRESET = '0' then
++ watchpoint <= (others => '1');
++ elsif rising_edge(CLOCK) and mode = modeWatch then
++ if r_set_n = '1' and nSET = '0' then
++ -- Increment selected digit on each button press
++ case digit is
++ when "00" => watchpoint(3 downto 0) <= std_logic_vector(unsigned(watchpoint(3 downto 0)) + 1);
++ when "01" => watchpoint(7 downto 4) <= std_logic_vector(unsigned(watchpoint(7 downto 4)) + 1);
++ when "10" => watchpoint(11 downto 8) <= std_logic_vector(unsigned(watchpoint(11 downto 8)) + 1);
++ when "11" => watchpoint(15 downto 12) <= std_logic_vector(unsigned(watchpoint(15 downto 12)) + 1);
++ when others => null;
++ end case;
++ end if;
++ end if;
++ end process;
++
++ -- Set breakpoint address
++ process(CLOCK,nRESET)
++ begin
++ if nRESET = '0' then
++ breakpoint <= (others => '1');
++ elsif rising_edge(CLOCK) and mode = modeBreak then
++ if r_set_n = '1' and nSET = '0' then
++ -- Increment selected digit on each button press
++ case digit is
++ when "00" => breakpoint(3 downto 0) <= std_logic_vector(unsigned(breakpoint(3 downto 0)) + 1);
++ when "01" => breakpoint(7 downto 4) <= std_logic_vector(unsigned(breakpoint(7 downto 4)) + 1);
++ when "10" => breakpoint(11 downto 8) <= std_logic_vector(unsigned(breakpoint(11 downto 8)) + 1);
++ when "11" => breakpoint(15 downto 12) <= std_logic_vector(unsigned(breakpoint(15 downto 12)) + 1);
++
++ when others => null;
++ end case;
++ end if;
++ end if;
++ end process;
++
++ -- CPU control logic
++ process(CLOCK,nRESET)
++ begin
++ if nRESET = '0' then
++ r_step_n <= '1';
++ halt <= '0';
++ resuming <= '0';
++ instr_addr <= (others => '0');
++ elsif rising_edge(CLOCK) then
++ -- Register single-step button
++ r_step_n <= nSTEP;
++
++ -- Once the CPU has run we can trigger a new halt
++ if CLKEN_IN = '1' then
++ resuming <= '0';
++ end if;
++
++ if SYNC = '1' then
++ -- Latch address of instruction fetch
++ instr_addr <= A_CPU;
++ end if;
++
++ -- Check for halt conditions if we are not resuming from a previous halt
++ if resuming = '0' then
++ if RUN = '0' and SYNC = '1' then
++ -- If not in RUN mode then halt on any instruction fetch
++ -- (single-step)
++ halt <= '1';
++ end if;
++ if A_CPU = breakpoint and SYNC = '1' then
++ -- Halt CPU when instruction fetched from breakpoint address
++ halt <= '1';
++ end if;
++ if A_CPU = watchpoint and SYNC = '0' and R_nW = '0' then
++ -- Halt CPU when data write to watchpoint address
++ halt <= '1';
++ end if;
++ end if;
++
++ -- Resume or single step when user presses "STEP" button
++ if r_step_n = '1' and nSTEP = '0' then
++ resuming <= '1';
++ halt <= '0';
++ end if;
++ end if;
++ end process;
++end architecture;
+diff --git a/i2c_loader.vhd b/i2c_loader.vhd
+index 35da643..61bdd22 100644
+--- a/i2c_loader.vhd
++++ b/i2c_loader.vhd
+@@ -1,304 +1,304 @@
+--- ZX Spectrum for Altera DE1
+---
+--- Copyright (c) 2009-2011 Mike Stirling
+---
+--- 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 agreement from the author.
+---
+--- * License is granted for non-commercial use only. A fee may not be charged
+--- for redistributions as source code or in synthesized/hardware form without
+--- specific prior written agreement from the author.
+---
+--- 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.
+---
+-
+-library IEEE;
+-use IEEE.STD_LOGIC_1164.ALL;
+-use IEEE.STD_LOGIC_ARITH.ALL;
+-use IEEE.STD_LOGIC_UNSIGNED.ALL;
+-use IEEE.STD_LOGIC_MISC.ALL; -- for AND_REDUCE
+-use IEEE.NUMERIC_STD.ALL;
+-
+-entity i2c_loader is
+-generic (
+- -- Address of slave to be loaded
+- device_address : integer := 16#1a#;
+- -- Number of retries to allow before stopping
+- num_retries : integer := 0;
+- -- Length of clock divider in bits. Resulting bus frequency is
+- -- CLK/2^(log2_divider + 2)
+- log2_divider : integer := 6
+-);
+-
+-port (
+- CLK : in std_logic;
+- nRESET : in std_logic;
+-
+- I2C_SCL : inout std_logic;
+- I2C_SDA : inout std_logic;
+-
+- IS_DONE : out std_logic;
+- IS_ERROR : out std_logic
+- );
+-end i2c_loader;
+-
+-architecture i2c_loader_arch of i2c_loader is
+-type regs is array(0 to 19) of std_logic_vector(7 downto 0);
+-constant init_regs : regs := (
+- -- Left line in, 0dB, unmute
+- X"00", X"17",
+- -- Right line in, 0dB, unmute
+- X"02", X"17",
+- -- Left headphone out, 0dB
+- X"04", X"79",
+- -- Right headphone out, 0dB
+- X"06", X"79",
+- -- Audio path, DAC enabled, Line in, Bypass off, mic unmuted
+- X"08", X"10",
+- -- Digital path, Unmute, HP filter enabled
+- X"0A", X"00",
+- -- Power down mic, clkout and xtal osc
+- X"0C", X"62",
+- -- Format 16-bit I2S, no bit inversion or phase changes
+- X"0E", X"02",
+- -- Sampling control, 8 kHz USB mode (MCLK = 250fs * 6)
+- X"10", X"0D",
+- -- Activate
+- X"12", X"01"
+- );
+--- Number of bursts (i.e. total number of registers)
+-constant burst_length : positive := 2;
+--- Number of bytes to transfer per burst
+-constant num_bursts : positive := (init_regs'length / burst_length);
+-
+-type state_t is (Idle, Start, Data, Ack, Stop, Pause, Done);
+-signal state : state_t;
+-signal phase : std_logic_vector(1 downto 0);
+-subtype nbit_t is integer range 0 to 7;
+-signal nbit : nbit_t;
+-subtype nbyte_t is integer range 0 to burst_length; -- +1 for address byte
+-signal nbyte : nbyte_t;
+-subtype thisbyte_t is integer range 0 to init_regs'length; -- +1 for "done"
+-signal thisbyte : thisbyte_t;
+-subtype retries_t is integer range 0 to num_retries;
+-signal retries : retries_t;
+-
+-signal clken : std_logic;
+-signal divider : std_logic_vector(log2_divider-1 downto 0);
+-signal shiftreg : std_logic_vector(7 downto 0);
+-signal scl_out : std_logic;
+-signal sda_out : std_logic;
+-signal nak : std_logic;
+-begin
+- -- Create open-drain outputs for I2C bus
+- I2C_SCL <= '0' when scl_out = '0' else 'Z';
+- I2C_SDA <= '0' when sda_out = '0' else 'Z';
+- -- Status outputs are driven both ways
+- IS_DONE <= '1' when state = Done else '0';
+- IS_ERROR <= nak;
+-
+- -- Generate clock enable for desired bus speed
+- clken <= AND_REDUCE(divider);
+- process(nRESET,CLK)
+- begin
+- if nRESET = '0' then
+- divider <= (others => '0');
+- elsif falling_edge(CLK) then
+- divider <= divider + '1';
+- end if;
+- end process;
+-
+- -- The I2C loader process
+- process(nRESET,CLK)
+- begin
+- if nRESET = '0' then
+- scl_out <= '1';
+- sda_out <= '1';
+- state <= Idle;
+- phase <= "00";
+- nbit <= 0;
+- nbyte <= 0;
+- thisbyte <= 0;
+- shiftreg <= (others => '0');
+- nak <= '0'; -- No error
+- retries <= num_retries;
+- elsif rising_edge(CLK) and clken = '1' then
+- -- Next phase by default
+- phase <= phase + 1;
+-
+- -- STATE: IDLE
+- if state = Idle then
+- -- Start loading the device registers straight away
+- -- A 'GO' bit could be polled here if required
+- state <= Start;
+- phase <= "00";
+- scl_out <= '1';
+- sda_out <= '1';
+-
+- -- STATE: START
+- elsif state = Start then
+- -- Generate START condition
+- case phase is
+- when "00" =>
+- -- Drop SDA first
+- sda_out <= '0';
+- when "10" =>
+- -- Then drop SCL
+- scl_out <= '0';
+- when "11" =>
+- -- Advance to next state
+- -- Shift register loaded with device slave address
+- state <= Data;
+- nbit <= 7;
+- shiftreg <= std_logic_vector(to_unsigned(device_address,7)) & '0'; -- writing
+- nbyte <= burst_length;
+- when others =>
+- null;
+- end case;
+-
+- -- STATE: DATA
+- elsif state = Data then
+- -- Generate data
+- case phase is
+- when "00" =>
+- -- Drop SCL
+- scl_out <= '0';
+- when "01" =>
+- -- Output data and shift (MSb first)
+- sda_out <= shiftreg(7);
+- shiftreg <= shiftreg(6 downto 0) & '0';
+- when "10" =>
+- -- Raise SCL
+- scl_out <= '1';
+- when "11" =>
+- -- Next bit or advance to next state when done
+- if nbit = 0 then
+- state <= Ack;
+- else
+- nbit <= nbit - 1;
+- end if;
+- when others =>
+- null;
+- end case;
+-
+- -- STATE: ACK
+- elsif state = Ack then
+- -- Generate ACK clock and check for error condition
+- case phase is
+- when "00" =>
+- -- Drop SCL
+- scl_out <= '0';
+- when "01" =>
+- -- Float data
+- sda_out <= '1';
+- when "10" =>
+- -- Sample ack bit
+- nak <= I2C_SDA;
+- if I2C_SDA = '1' then
+- -- Error
+- nbyte <= 0; -- Close this burst and skip remaining registers
+- thisbyte <= init_regs'length;
+- else
+- -- Hold ACK to avoid spurious stops - this seems to fix a
+- -- problem with the Wolfson codec which releases the ACK
+- -- right on the falling edge of the clock pulse. It looks like
+- -- the device interprets this is a STOP condition and then fails
+- -- to acknowledge the next byte. We can avoid this by holding the
+- -- ACK condition for a little longer.
+- sda_out <= '0';
+- end if;
+- -- Raise SCL
+- scl_out <= '1';
+- when "11" =>
+- -- Advance to next state
+- if nbyte = 0 then
+- -- No more bytes in this burst - generate a STOP
+- state <= Stop;
+- else
+- -- Generate next byte
+- state <= Data;
+- nbit <= 7;
+- shiftreg <= init_regs(thisbyte);
+- nbyte <= nbyte - 1;
+- thisbyte <= thisbyte + 1;
+- end if;
+- when others =>
+- null;
+- end case;
+-
+- -- STATE: STOP
+- elsif state = Stop then
+- -- Generate STOP condition
+- case phase is
+- when "00" =>
+- -- Drop SCL first
+- scl_out <= '0';
+- when "01" =>
+- -- Drop SDA
+- sda_out <= '0';
+- when "10" =>
+- -- Raise SCL
+- scl_out <= '1';
+- when "11" =>
+- if thisbyte = init_regs'length then
+- -- All registers done, advance to finished state. This will
+- -- bring SDA high while SCL is still high, completing the STOP
+- -- condition
+- state <= Done;
+- else
+- -- Load the next register after a short delay
+- state <= Pause;
+- end if;
+- when others =>
+- null;
+- end case;
+-
+- -- STATE: PAUSE
+- elsif state = Pause then
+- -- Delay for one cycle of 'phase' then start the next burst
+- scl_out <= '1';
+- sda_out <= '1';
+- if phase = "11" then
+- state <= Start;
+- end if;
+-
+- -- STATE: DONE
+- else
+- -- Finished
+- scl_out <= '1';
+- sda_out <= '1';
+-
+- if nak = '1' and retries > 0 then
+- -- We can retry in the event of a NAK in case the
+- -- slave got out of sync for some reason
+- retries <= retries - 1;
+- state <= Idle;
+- end if;
+- end if;
+- end if;
+- end process;
+-end i2c_loader_arch;
+-
++-- ZX Spectrum for Altera DE1
++--
++-- Copyright (c) 2009-2011 Mike Stirling
++--
++-- 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 agreement from the author.
++--
++-- * License is granted for non-commercial use only. A fee may not be charged
++-- for redistributions as source code or in synthesized/hardware form without
++-- specific prior written agreement from the author.
++--
++-- 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.
++--
++
++library IEEE;
++use IEEE.STD_LOGIC_1164.ALL;
++use IEEE.STD_LOGIC_ARITH.ALL;
++use IEEE.STD_LOGIC_UNSIGNED.ALL;
++use IEEE.STD_LOGIC_MISC.ALL; -- for AND_REDUCE
++use IEEE.NUMERIC_STD.ALL;
++
++entity i2c_loader is
++generic (
++ -- Address of slave to be loaded
++ device_address : integer := 16#1a#;
++ -- Number of retries to allow before stopping
++ num_retries : integer := 0;
++ -- Length of clock divider in bits. Resulting bus frequency is
++ -- CLK/2^(log2_divider + 2)
++ log2_divider : integer := 6
++);
++
++port (
++ CLK : in std_logic;
++ nRESET : in std_logic;
++
++ I2C_SCL : inout std_logic;
++ I2C_SDA : inout std_logic;
++
++ IS_DONE : out std_logic;
++ IS_ERROR : out std_logic
++ );
++end i2c_loader;
++
++architecture i2c_loader_arch of i2c_loader is
++type regs is array(0 to 19) of std_logic_vector(7 downto 0);
++constant init_regs : regs := (
++ -- Left line in, 0dB, unmute
++ X"00", X"17",
++ -- Right line in, 0dB, unmute
++ X"02", X"17",
++ -- Left headphone out, 0dB
++ X"04", X"79",
++ -- Right headphone out, 0dB
++ X"06", X"79",
++ -- Audio path, DAC enabled, Line in, Bypass off, mic unmuted
++ X"08", X"10",
++ -- Digital path, Unmute, HP filter enabled
++ X"0A", X"00",
++ -- Power down mic, clkout and xtal osc
++ X"0C", X"62",
++ -- Format 16-bit I2S, no bit inversion or phase changes
++ X"0E", X"02",
++ -- Sampling control, 8 kHz USB mode (MCLK = 250fs * 6)
++ X"10", X"0D",
++ -- Activate
++ X"12", X"01"
++ );
++-- Number of bursts (i.e. total number of registers)
++constant burst_length : positive := 2;
++-- Number of bytes to transfer per burst
++constant num_bursts : positive := (init_regs'length / burst_length);
++
++type state_t is (Idle, Start, Data, Ack, Stop, Pause, Done);
++signal state : state_t;
++signal phase : std_logic_vector(1 downto 0);
++subtype nbit_t is integer range 0 to 7;
++signal nbit : nbit_t;
++subtype nbyte_t is integer range 0 to burst_length; -- +1 for address byte
++signal nbyte : nbyte_t;
++subtype thisbyte_t is integer range 0 to init_regs'length; -- +1 for "done"
++signal thisbyte : thisbyte_t;
++subtype retries_t is integer range 0 to num_retries;
++signal retries : retries_t;
++
++signal clken : std_logic;
++signal divider : std_logic_vector(log2_divider-1 downto 0);
++signal shiftreg : std_logic_vector(7 downto 0);
++signal scl_out : std_logic;
++signal sda_out : std_logic;
++signal nak : std_logic;
++begin
++ -- Create open-drain outputs for I2C bus
++ I2C_SCL <= '0' when scl_out = '0' else 'Z';
++ I2C_SDA <= '0' when sda_out = '0' else 'Z';
++ -- Status outputs are driven both ways
++ IS_DONE <= '1' when state = Done else '0';
++ IS_ERROR <= nak;
++
++ -- Generate clock enable for desired bus speed
++ clken <= AND_REDUCE(divider);
++ process(nRESET,CLK)
++ begin
++ if nRESET = '0' then
++ divider <= (others => '0');
++ elsif falling_edge(CLK) then
++ divider <= divider + '1';
++ end if;
++ end process;
++
++ -- The I2C loader process
++ process(nRESET,CLK)
++ begin
++ if nRESET = '0' then
++ scl_out <= '1';
++ sda_out <= '1';
++ state <= Idle;
++ phase <= "00";
++ nbit <= 0;
++ nbyte <= 0;
++ thisbyte <= 0;
++ shiftreg <= (others => '0');
++ nak <= '0'; -- No error
++ retries <= num_retries;
++ elsif rising_edge(CLK) and clken = '1' then
++ -- Next phase by default
++ phase <= phase + 1;
++
++ -- STATE: IDLE
++ if state = Idle then
++ -- Start loading the device registers straight away
++ -- A 'GO' bit could be polled here if required
++ state <= Start;
++ phase <= "00";
++ scl_out <= '1';
++ sda_out <= '1';
++
++ -- STATE: START
++ elsif state = Start then
++ -- Generate START condition
++ case phase is
++ when "00" =>
++ -- Drop SDA first
++ sda_out <= '0';
++ when "10" =>
++ -- Then drop SCL
++ scl_out <= '0';
++ when "11" =>
++ -- Advance to next state
++ -- Shift register loaded with device slave address
++ state <= Data;
++ nbit <= 7;
++ shiftreg <= std_logic_vector(to_unsigned(device_address,7)) & '0'; -- writing
++ nbyte <= burst_length;
++ when others =>
++ null;
++ end case;
++
++ -- STATE: DATA
++ elsif state = Data then
++ -- Generate data
++ case phase is
++ when "00" =>
++ -- Drop SCL
++ scl_out <= '0';
++ when "01" =>
++ -- Output data and shift (MSb first)
++ sda_out <= shiftreg(7);
++ shiftreg <= shiftreg(6 downto 0) & '0';
++ when "10" =>
++ -- Raise SCL
++ scl_out <= '1';
++ when "11" =>
++ -- Next bit or advance to next state when done
++ if nbit = 0 then
++ state <= Ack;
++ else
++ nbit <= nbit - 1;
++ end if;
++ when others =>
++ null;
++ end case;
++
++ -- STATE: ACK
++ elsif state = Ack then
++ -- Generate ACK clock and check for error condition
++ case phase is
++ when "00" =>
++ -- Drop SCL
++ scl_out <= '0';
++ when "01" =>
++ -- Float data
++ sda_out <= '1';
++ when "10" =>
++ -- Sample ack bit
++ nak <= I2C_SDA;
++ if I2C_SDA = '1' then
++ -- Error
++ nbyte <= 0; -- Close this burst and skip remaining registers
++ thisbyte <= init_regs'length;
++ else
++ -- Hold ACK to avoid spurious stops - this seems to fix a
++ -- problem with the Wolfson codec which releases the ACK
++ -- right on the falling edge of the clock pulse. It looks like
++ -- the device interprets this is a STOP condition and then fails
++ -- to acknowledge the next byte. We can avoid this by holding the
++ -- ACK condition for a little longer.
++ sda_out <= '0';
++ end if;
++ -- Raise SCL
++ scl_out <= '1';
++ when "11" =>
++ -- Advance to next state
++ if nbyte = 0 then
++ -- No more bytes in this burst - generate a STOP
++ state <= Stop;
++ else
++ -- Generate next byte
++ state <= Data;
++ nbit <= 7;
++ shiftreg <= init_regs(thisbyte);
++ nbyte <= nbyte - 1;
++ thisbyte <= thisbyte + 1;
++ end if;
++ when others =>
++ null;
++ end case;
++
++ -- STATE: STOP
++ elsif state = Stop then
++ -- Generate STOP condition
++ case phase is
++ when "00" =>
++ -- Drop SCL first
++ scl_out <= '0';
++ when "01" =>
++ -- Drop SDA
++ sda_out <= '0';
++ when "10" =>
++ -- Raise SCL
++ scl_out <= '1';
++ when "11" =>
++ if thisbyte = init_regs'length then
++ -- All registers done, advance to finished state. This will
++ -- bring SDA high while SCL is still high, completing the STOP
++ -- condition
++ state <= Done;
++ else
++ -- Load the next register after a short delay
++ state <= Pause;
++ end if;
++ when others =>
++ null;
++ end case;
++
++ -- STATE: PAUSE
++ elsif state = Pause then
++ -- Delay for one cycle of 'phase' then start the next burst
++ scl_out <= '1';
++ sda_out <= '1';
++ if phase = "11" then
++ state <= Start;
++ end if;
++
++ -- STATE: DONE
++ else
++ -- Finished
++ scl_out <= '1';
++ sda_out <= '1';
++
++ if nak = '1' and retries > 0 then
++ -- We can retry in the event of a NAK in case the
++ -- slave got out of sync for some reason
++ retries <= retries - 1;
++ state <= Idle;
++ end if;
++ end if;
++ end if;
++ end process;
++end i2c_loader_arch;
++
+diff --git a/i2s_intf.vhd b/i2s_intf.vhd
+index e15ce2c..49b6efb 100644
+--- a/i2s_intf.vhd
++++ b/i2s_intf.vhd
+@@ -1,37 +1,37 @@
+ -- ZX Spectrum for Altera DE1
+ --
+--- Copyright (c) 2009-2011 Mike Stirling
+---
+--- 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 agreement from the author.
+---
+--- * License is granted for non-commercial use only. A fee may not be charged
+--- for redistributions as source code or in synthesized/hardware form without
+--- specific prior written agreement from the author.
+---
+--- 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
++-- Copyright (c) 2009-2011 Mike Stirling
++--
++-- 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 agreement from the author.
++--
++-- * License is granted for non-commercial use only. A fee may not be charged
++-- for redistributions as source code or in synthesized/hardware form without
++-- specific prior written agreement from the author.
++--
++-- 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.
+ --
+
+diff --git a/keyboard.vhd b/keyboard.vhd
+index c0b8603..cba4054 100644
+--- a/keyboard.vhd
++++ b/keyboard.vhd
+@@ -1,294 +1,294 @@
+--- BBC Micro for Altera DE1
+---
+--- Copyright (c) 2011 Mike Stirling
+---
+--- 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 agreement from the author.
+---
+--- * License is granted for non-commercial use only. A fee may not be charged
+--- for redistributions as source code or in synthesized/hardware form without
+--- specific prior written agreement from the author.
+---
+--- 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.
+---
+--- BBC keyboard implementation with interface to PS/2
+---
+--- (C) 2011 Mike Stirling
+---
+-
+-library IEEE;
+-use IEEE.STD_LOGIC_1164.ALL;
+-use IEEE.NUMERIC_STD.ALL;
+-
+-entity keyboard is
+-port (
+- CLOCK : in std_logic;
+- nRESET : in std_logic;
+- CLKEN_1MHZ : in std_logic;
+-
+- -- PS/2 interface
+- PS2_CLK : in std_logic;
+- PS2_DATA : in std_logic;
+-
+- -- If 1 then column is incremented automatically at
+- -- 1 MHz rate
+- AUTOSCAN : in std_logic;
+-
+- COLUMN : in std_logic_vector(3 downto 0);
+- ROW : in std_logic_vector(2 downto 0);
+-
+- -- 1 when currently selected key is down (AUTOSCAN disabled)
+- KEYPRESS : out std_logic;
+- -- 1 when any key is down (except row 0)
+- INT : out std_logic;
+- -- BREAK key output - 1 when pressed
+- BREAK_OUT : out std_logic;
+-
+- -- DIP switch inputs
+- DIP_SWITCH : in std_logic_vector(7 downto 0)
+- );
+-end entity;
+-
+-architecture rtl of keyboard is
+-
+--- PS/2 interface
+-component ps2_intf is
+-generic (filter_length : positive := 8);
+-port(
+- CLK : in std_logic;
+- nRESET : in std_logic;
+-
+- -- PS/2 interface (could be bi-dir)
+- PS2_CLK : in std_logic;
+- PS2_DATA : in std_logic;
+-
+- -- Byte-wide data interface - only valid for one clock
+- -- so must be latched externally if required
+- DATA : out std_logic_vector(7 downto 0);
+- VALID : out std_logic;
+- ERROR : out std_logic
+- );
+-end component;
+-
+--- Interface to PS/2 block
+-signal keyb_data : std_logic_vector(7 downto 0);
+-signal keyb_valid : std_logic;
+-signal keyb_error : std_logic;
+-
+--- Internal signals
+-type key_matrix is array(0 to 15) of std_logic_vector(7 downto 0);
+-signal keys : key_matrix;
+-signal col : unsigned(3 downto 0);
+-signal release : std_logic;
+-signal extended : std_logic;
+-begin
+-
+- ps2 : ps2_intf port map (
+- CLOCK, nRESET,
+- PS2_CLK, PS2_DATA,
+- keyb_data, keyb_valid, keyb_error
+- );
+-
+- -- Column counts automatically when AUTOSCAN is enabled, otherwise
+- -- value is loaded from external input
+- process(CLOCK,nRESET)
+- begin
+- if nRESET = '0' then
+- col <= (others => '0');
+- elsif rising_edge(CLOCK) then
+- if AUTOSCAN = '0' then
+- -- If autoscan disabled then transfer current COLUMN to counter
+- -- immediately (don't wait for next 1 MHz cycle)
+- col <= unsigned(COLUMN);
+- elsif CLKEN_1MHZ = '1' then
+- -- Otherwise increment the counter once per 1 MHz tick
+- col <= col + 1;
+- end if;
+- end if;
+- end process;
+-
+- -- Generate interrupt if any key in currently scanned column is pressed
+- -- (apart from in row 0). Output selected key status if autoscan disabled.
+- process(keys,col,ROW,AUTOSCAN)
+- variable k : std_logic_vector(7 downto 0);
+- begin
+- -- Shortcut to current key column
+- k := keys(to_integer(col));
+-
+- -- Interrupt if any key pressed in rows 1 to 7.
+- INT <= k(7) or k(6) or k(5) or k(4) or k(3) or k(2) or k(1);
+-
+- -- Determine which key is pressed
+- -- Inhibit output during auto-scan
+- if AUTOSCAN = '0' then
+- KEYPRESS <= k(to_integer(unsigned(ROW)));
+- else
+- KEYPRESS <= '0';
+- end if;
+- end process;
+-
+- -- Decode PS/2 data
+- process(CLOCK,nRESET)
+- begin
+- if nRESET = '0' then
+- release <= '0';
+- extended <= '0';
+-
+- BREAK_OUT <= '0';
+-
+- keys(0) <= (others => '0');
+- keys(1) <= (others => '0');
+- keys(2) <= (others => '0');
+- keys(3) <= (others => '0');
+- keys(4) <= (others => '0');
+- keys(5) <= (others => '0');
+- keys(6) <= (others => '0');
+- keys(7) <= (others => '0');
+- keys(8) <= (others => '0');
+- keys(9) <= (others => '0');
+- -- These non-existent rows are used in the BBC master
+- keys(10) <= (others => '0');
+- keys(11) <= (others => '0');
+- keys(12) <= (others => '0');
+- keys(13) <= (others => '0');
+- keys(14) <= (others => '0');
+- keys(15) <= (others => '0');
+- elsif rising_edge(CLOCK) then
+- -- Copy DIP switches through to row 0
+- keys(2)(0) <= DIP_SWITCH(7);
+- keys(3)(0) <= DIP_SWITCH(6);
+- keys(4)(0) <= DIP_SWITCH(5);
+- keys(5)(0) <= DIP_SWITCH(4);
+- keys(6)(0) <= DIP_SWITCH(3);
+- keys(7)(0) <= DIP_SWITCH(2);
+- keys(8)(0) <= DIP_SWITCH(1);
+- keys(9)(0) <= DIP_SWITCH(0);
+-
+- if keyb_valid = '1' then
+- -- Decode keyboard input
+- if keyb_data = X"e0" then
+- -- Extended key code follows
+- extended <= '1';
+- elsif keyb_data = X"f0" then
+- -- Release code follows
+- release <= '1';
+- else
+- -- Cancel extended/release flags for next time
+- release <= '0';
+- extended <= '0';
+-
+- -- Decode scan codes
+- case keyb_data is
+- when X"12" => keys(0)(0) <= not release; -- Left SHIFT
+- when X"59" => keys(0)(0) <= not release; -- Right SHIFT
+- when X"15" => keys(0)(1) <= not release; -- Q
+- when X"09" => keys(0)(2) <= not release; -- F10 (F0)
+- when X"16" => keys(0)(3) <= not release; -- 1
+- when X"58" => keys(0)(4) <= not release; -- CAPS LOCK
+- when X"11" => keys(0)(5) <= not release; -- LEFT ALT (SHIFT LOCK)
+- when X"0D" => keys(0)(6) <= not release; -- TAB
+- when X"76" => keys(0)(7) <= not release; -- ESCAPE
+- when X"14" => keys(1)(0) <= not release; -- LEFT/RIGHT CTRL (CTRL)
+- when X"26" => keys(1)(1) <= not release; -- 3
+- when X"1D" => keys(1)(2) <= not release; -- W
+- when X"1E" => keys(1)(3) <= not release; -- 2
+- when X"1C" => keys(1)(4) <= not release; -- A
+- when X"1B" => keys(1)(5) <= not release; -- S
+- when X"1A" => keys(1)(6) <= not release; -- Z
+- when X"05" => keys(1)(7) <= not release; -- F1
+- when X"25" => keys(2)(1) <= not release; -- 4
+- when X"24" => keys(2)(2) <= not release; -- E
+- when X"23" => keys(2)(3) <= not release; -- D
+- when X"22" => keys(2)(4) <= not release; -- X
+- when X"21" => keys(2)(5) <= not release; -- C
+- when X"29" => keys(2)(6) <= not release; -- SPACE
+- when X"06" => keys(2)(7) <= not release; -- F2
+- when X"2E" => keys(3)(1) <= not release; -- 5
+- when X"2C" => keys(3)(2) <= not release; -- T
+- when X"2D" => keys(3)(3) <= not release; -- R
+- when X"2B" => keys(3)(4) <= not release; -- F
+- when X"34" => keys(3)(5) <= not release; -- G
+- when X"2A" => keys(3)(6) <= not release; -- V
+- when X"04" => keys(3)(7) <= not release; -- F3
+- when X"0C" => keys(4)(1) <= not release; -- F4
+- when X"3D" => keys(4)(2) <= not release; -- 7
+- when X"36" => keys(4)(3) <= not release; -- 6
+- when X"35" => keys(4)(4) <= not release; -- Y
+- when X"33" => keys(4)(5) <= not release; -- H
+- when X"32" => keys(4)(6) <= not release; -- B
+- when X"03" => keys(4)(7) <= not release; -- F5
+- when X"3E" => keys(5)(1) <= not release; -- 8
+- when X"43" => keys(5)(2) <= not release; -- I
+- when X"3C" => keys(5)(3) <= not release; -- U
+- when X"3B" => keys(5)(4) <= not release; -- J
+- when X"31" => keys(5)(5) <= not release; -- N
+- when X"3A" => keys(5)(6) <= not release; -- M
+- when X"0B" => keys(5)(7) <= not release; -- F6
+- when X"83" => keys(6)(1) <= not release; -- F7
+- when X"46" => keys(6)(2) <= not release; -- 9
+- when X"44" => keys(6)(3) <= not release; -- O
+- when X"42" => keys(6)(4) <= not release; -- K
+- when X"4B" => keys(6)(5) <= not release; -- L
+- when X"41" => keys(6)(6) <= not release; -- ,
+- when X"0A" => keys(6)(7) <= not release; -- F8
+- when X"4E" => keys(7)(1) <= not release; -- -
+- when X"45" => keys(7)(2) <= not release; -- 0
+- when X"4D" => keys(7)(3) <= not release; -- P
+- when X"0E" => keys(7)(4) <= not release; -- ` (@)
+- when X"4C" => keys(7)(5) <= not release; -- ;
+- when X"49" => keys(7)(6) <= not release; -- .
+- when X"01" => keys(7)(7) <= not release; -- F9
+- when X"55" => keys(8)(1) <= not release; -- = (^)
+- when X"5D" => keys(8)(2) <= not release; -- # (_)
+- when X"54" => keys(8)(3) <= not release; -- [
+- when X"52" => keys(8)(4) <= not release; -- '
+- when X"5B" => keys(8)(5) <= not release; -- ]
+- when X"4A" => keys(8)(6) <= not release; -- /
+- when X"61" => keys(8)(7) <= not release; -- \
+- when X"6B" => keys(9)(1) <= not release; -- LEFT
+- when X"72" => keys(9)(2) <= not release; -- DOWN
+- when X"75" => keys(9)(3) <= not release; -- UP
+- when X"5A" => keys(9)(4) <= not release; -- RETURN
+- when X"66" => keys(9)(5) <= not release; -- BACKSPACE (DELETE)
+- when X"69" => keys(9)(6) <= not release; -- END (COPY)
+- when X"74" => keys(9)(7) <= not release; -- RIGHT
+-
+- -- F12 is used for the BREAK key, which in the real BBC asserts
+- -- reset. Here we pass this out to the top level which may
+- -- optionally OR it in to the system reset
+- when X"07" => BREAK_OUT <= not release; -- F12 (BREAK)
+-
+- when others => null;
+- end case;
+-
+- end if;
+- end if;
+- end if;
+- end process;
+-
+-end architecture;
+-
+-
++-- BBC Micro for Altera DE1
++--
++-- Copyright (c) 2011 Mike Stirling
++--
++-- 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 agreement from the author.
++--
++-- * License is granted for non-commercial use only. A fee may not be charged
++-- for redistributions as source code or in synthesized/hardware form without
++-- specific prior written agreement from the author.
++--
++-- 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.
++--
++-- BBC keyboard implementation with interface to PS/2
++--
++-- (C) 2011 Mike Stirling
++--
++
++library IEEE;
++use IEEE.STD_LOGIC_1164.ALL;
++use IEEE.NUMERIC_STD.ALL;
++
++entity keyboard is
++port (
++ CLOCK : in std_logic;
++ nRESET : in std_logic;
++ CLKEN_1MHZ : in std_logic;
++
++ -- PS/2 interface
++ PS2_CLK : in std_logic;
++ PS2_DATA : in std_logic;
++
++ -- If 1 then column is incremented automatically at
++ -- 1 MHz rate
++ AUTOSCAN : in std_logic;
++
++ COLUMN : in std_logic_vector(3 downto 0);
++ ROW : in std_logic_vector(2 downto 0);
++
++ -- 1 when currently selected key is down (AUTOSCAN disabled)
++ KEYPRESS : out std_logic;
++ -- 1 when any key is down (except row 0)
++ INT : out std_logic;
++ -- BREAK key output - 1 when pressed
++ BREAK_OUT : out std_logic;
++
++ -- DIP switch inputs
++ DIP_SWITCH : in std_logic_vector(7 downto 0)
++ );
++end entity;
++
++architecture rtl of keyboard is
++
++-- PS/2 interface
++component ps2_intf is
++generic (filter_length : positive := 8);
++port(
++ CLK : in std_logic;
++ nRESET : in std_logic;
++
++ -- PS/2 interface (could be bi-dir)
++ PS2_CLK : in std_logic;
++ PS2_DATA : in std_logic;
++
++ -- Byte-wide data interface - only valid for one clock
++ -- so must be latched externally if required
++ DATA : out std_logic_vector(7 downto 0);
++ VALID : out std_logic;
++ ERROR : out std_logic
++ );
++end component;
++
++-- Interface to PS/2 block
++signal keyb_data : std_logic_vector(7 downto 0);
++signal keyb_valid : std_logic;
++signal keyb_error : std_logic;
++
++-- Internal signals
++type key_matrix is array(0 to 15) of std_logic_vector(7 downto 0);
++signal keys : key_matrix;
++signal col : unsigned(3 downto 0);
++signal release : std_logic;
++signal extended : std_logic;
++begin
++
++ ps2 : ps2_intf port map (
++ CLOCK, nRESET,
++ PS2_CLK, PS2_DATA,
++ keyb_data, keyb_valid, keyb_error
++ );
++
++ -- Column counts automatically when AUTOSCAN is enabled, otherwise
++ -- value is loaded from external input
++ process(CLOCK,nRESET)
++ begin
++ if nRESET = '0' then
++ col <= (others => '0');
++ elsif rising_edge(CLOCK) then
++ if AUTOSCAN = '0' then
++ -- If autoscan disabled then transfer current COLUMN to counter
++ -- immediately (don't wait for next 1 MHz cycle)
++ col <= unsigned(COLUMN);
++ elsif CLKEN_1MHZ = '1' then
++ -- Otherwise increment the counter once per 1 MHz tick
++ col <= col + 1;
++ end if;
++ end if;
++ end process;
++
++ -- Generate interrupt if any key in currently scanned column is pressed
++ -- (apart from in row 0). Output selected key status if autoscan disabled.
++ process(keys,col,ROW,AUTOSCAN)
++ variable k : std_logic_vector(7 downto 0);
++ begin
++ -- Shortcut to current key column
++ k := keys(to_integer(col));
++
++ -- Interrupt if any key pressed in rows 1 to 7.
++ INT <= k(7) or k(6) or k(5) or k(4) or k(3) or k(2) or k(1);
++
++ -- Determine which key is pressed
++ -- Inhibit output during auto-scan
++ if AUTOSCAN = '0' then
++ KEYPRESS <= k(to_integer(unsigned(ROW)));
++ else
++ KEYPRESS <= '0';
++ end if;
++ end process;
++
++ -- Decode PS/2 data
++ process(CLOCK,nRESET)
++ begin
++ if nRESET = '0' then
++ release <= '0';
++ extended <= '0';
++
++ BREAK_OUT <= '0';
++
++ keys(0) <= (others => '0');
++ keys(1) <= (others => '0');
++ keys(2) <= (others => '0');
++ keys(3) <= (others => '0');
++ keys(4) <= (others => '0');
++ keys(5) <= (others => '0');
++ keys(6) <= (others => '0');
++ keys(7) <= (others => '0');
++ keys(8) <= (others => '0');
++ keys(9) <= (others => '0');
++ -- These non-existent rows are used in the BBC master
++ keys(10) <= (others => '0');
++ keys(11) <= (others => '0');
++ keys(12) <= (others => '0');
++ keys(13) <= (others => '0');
++ keys(14) <= (others => '0');
++ keys(15) <= (others => '0');
++ elsif rising_edge(CLOCK) then
++ -- Copy DIP switches through to row 0
++ keys(2)(0) <= DIP_SWITCH(7);
++ keys(3)(0) <= DIP_SWITCH(6);
++ keys(4)(0) <= DIP_SWITCH(5);
++ keys(5)(0) <= DIP_SWITCH(4);
++ keys(6)(0) <= DIP_SWITCH(3);
++ keys(7)(0) <= DIP_SWITCH(2);
++ keys(8)(0) <= DIP_SWITCH(1);
++ keys(9)(0) <= DIP_SWITCH(0);
++
++ if keyb_valid = '1' then
++ -- Decode keyboard input
++ if keyb_data = X"e0" then
++ -- Extended key code follows
++ extended <= '1';
++ elsif keyb_data = X"f0" then
++ -- Release code follows
++ release <= '1';
++ else
++ -- Cancel extended/release flags for next time
++ release <= '0';
++ extended <= '0';
++
++ -- Decode scan codes
++ case keyb_data is
++ when X"12" => keys(0)(0) <= not release; -- Left SHIFT
++ when X"59" => keys(0)(0) <= not release; -- Right SHIFT
++ when X"15" => keys(0)(1) <= not release; -- Q
++ when X"09" => keys(0)(2) <= not release; -- F10 (F0)
++ when X"16" => keys(0)(3) <= not release; -- 1
++ when X"58" => keys(0)(4) <= not release; -- CAPS LOCK
++ when X"11" => keys(0)(5) <= not release; -- LEFT ALT (SHIFT LOCK)
++ when X"0D" => keys(0)(6) <= not release; -- TAB
++ when X"76" => keys(0)(7) <= not release; -- ESCAPE
++ when X"14" => keys(1)(0) <= not release; -- LEFT/RIGHT CTRL (CTRL)
++ when X"26" => keys(1)(1) <= not release; -- 3
++ when X"1D" => keys(1)(2) <= not release; -- W
++ when X"1E" => keys(1)(3) <= not release; -- 2
++ when X"1C" => keys(1)(4) <= not release; -- A
++ when X"1B" => keys(1)(5) <= not release; -- S
++ when X"1A" => keys(1)(6) <= not release; -- Z
++ when X"05" => keys(1)(7) <= not release; -- F1
++ when X"25" => keys(2)(1) <= not release; -- 4
++ when X"24" => keys(2)(2) <= not release; -- E
++ when X"23" => keys(2)(3) <= not release; -- D
++ when X"22" => keys(2)(4) <= not release; -- X
++ when X"21" => keys(2)(5) <= not release; -- C
++ when X"29" => keys(2)(6) <= not release; -- SPACE
++ when X"06" => keys(2)(7) <= not release; -- F2
++ when X"2E" => keys(3)(1) <= not release; -- 5
++ when X"2C" => keys(3)(2) <= not release; -- T
++ when X"2D" => keys(3)(3) <= not release; -- R
++ when X"2B" => keys(3)(4) <= not release; -- F
++ when X"34" => keys(3)(5) <= not release; -- G
++ when X"2A" => keys(3)(6) <= not release; -- V
++ when X"04" => keys(3)(7) <= not release; -- F3
++ when X"0C" => keys(4)(1) <= not release; -- F4
++ when X"3D" => keys(4)(2) <= not release; -- 7
++ when X"36" => keys(4)(3) <= not release; -- 6
++ when X"35" => keys(4)(4) <= not release; -- Y
++ when X"33" => keys(4)(5) <= not release; -- H
++ when X"32" => keys(4)(6) <= not release; -- B
++ when X"03" => keys(4)(7) <= not release; -- F5
++ when X"3E" => keys(5)(1) <= not release; -- 8
++ when X"43" => keys(5)(2) <= not release; -- I
++ when X"3C" => keys(5)(3) <= not release; -- U
++ when X"3B" => keys(5)(4) <= not release; -- J
++ when X"31" => keys(5)(5) <= not release; -- N
++ when X"3A" => keys(5)(6) <= not release; -- M
++ when X"0B" => keys(5)(7) <= not release; -- F6
++ when X"83" => keys(6)(1) <= not release; -- F7
++ when X"46" => keys(6)(2) <= not release; -- 9
++ when X"44" => keys(6)(3) <= not release; -- O
++ when X"42" => keys(6)(4) <= not release; -- K
++ when X"4B" => keys(6)(5) <= not release; -- L
++ when X"41" => keys(6)(6) <= not release; -- ,
++ when X"0A" => keys(6)(7) <= not release; -- F8
++ when X"4E" => keys(7)(1) <= not release; -- -
++ when X"45" => keys(7)(2) <= not release; -- 0
++ when X"4D" => keys(7)(3) <= not release; -- P
++ when X"0E" => keys(7)(4) <= not release; -- ` (@)
++ when X"4C" => keys(7)(5) <= not release; -- ;
++ when X"49" => keys(7)(6) <= not release; -- .
++ when X"01" => keys(7)(7) <= not release; -- F9
++ when X"55" => keys(8)(1) <= not release; -- = (^)
++ when X"5D" => keys(8)(2) <= not release; -- # (_)
++ when X"54" => keys(8)(3) <= not release; -- [
++ when X"52" => keys(8)(4) <= not release; -- '
++ when X"5B" => keys(8)(5) <= not release; -- ]
++ when X"4A" => keys(8)(6) <= not release; -- /
++ when X"61" => keys(8)(7) <= not release; -- \
++ when X"6B" => keys(9)(1) <= not release; -- LEFT
++ when X"72" => keys(9)(2) <= not release; -- DOWN
++ when X"75" => keys(9)(3) <= not release; -- UP
++ when X"5A" => keys(9)(4) <= not release; -- RETURN
++ when X"66" => keys(9)(5) <= not release; -- BACKSPACE (DELETE)
++ when X"69" => keys(9)(6) <= not release; -- END (COPY)
++ when X"74" => keys(9)(7) <= not release; -- RIGHT
++
++ -- F12 is used for the BREAK key, which in the real BBC asserts
++ -- reset. Here we pass this out to the top level which may
++ -- optionally OR it in to the system reset
++ when X"07" => BREAK_OUT <= not release; -- F12 (BREAK)
++
++ when others => null;
++ end case;
++
++ end if;
++ end if;
++ end if;
++ end process;
++
++end architecture;
++
++
+diff --git a/m6522.vhd b/m6522.vhd
+index e01ed10..5c0d341 100644
+--- a/m6522.vhd
++++ b/m6522.vhd
+@@ -1,886 +1,886 @@
+---
+--- A simulation model of VIC20 hardware
+--- Copyright (c) MikeJ - March 2003
+---
+--- 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 CODE 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.
+---
+--- You are responsible for any legal issues arising from your use of this code.
+---
+--- The latest version of this file can be found at: www.fpgaarcade.com
+---
+--- Email vic20@fpgaarcade.com
+---
+---
+--- Revision list
+---
+--- version 002 fix from Mark McDougall, untested
+--- version 001 initial release
+--- not very sure about the shift register, documentation is a bit light.
+-
+-library ieee ;
+- use ieee.std_logic_1164.all ;
+- use ieee.std_logic_unsigned.all;
+- use ieee.numeric_std.all;
+-
+---library UNISIM;
+--- use UNISIM.Vcomponents.all;
+-
+-entity M6522 is
+- port (
+-
+- I_RS : in std_logic_vector(3 downto 0);
+- I_DATA : in std_logic_vector(7 downto 0);
+- O_DATA : out std_logic_vector(7 downto 0);
+- O_DATA_OE_L : out std_logic;
+-
+- I_RW_L : in std_logic;
+- I_CS1 : in std_logic;
+- I_CS2_L : in std_logic;
+-
+- O_IRQ_L : out std_logic; -- note, not open drain
+- -- port a
+- I_CA1 : in std_logic;
+- I_CA2 : in std_logic;
+- O_CA2 : out std_logic;
+- O_CA2_OE_L : out std_logic;
+-
+- I_PA : in std_logic_vector(7 downto 0);
+- O_PA : out std_logic_vector(7 downto 0);
+- O_PA_OE_L : out std_logic_vector(7 downto 0);
+-
+- -- port b
+- I_CB1 : in std_logic;
+- O_CB1 : out std_logic;
+- O_CB1_OE_L : out std_logic;
+-
+- I_CB2 : in std_logic;
+- O_CB2 : out std_logic;
+- O_CB2_OE_L : out std_logic;
+-
+- I_PB : in std_logic_vector(7 downto 0);
+- O_PB : out std_logic_vector(7 downto 0);
+- O_PB_OE_L : out std_logic_vector(7 downto 0);
+-
+- I_P2_H : in std_logic; -- high for phase 2 clock ____----__
+- RESET_L : in std_logic;
+- ENA_4 : in std_logic; -- clk enable
+- CLK : in std_logic
+- );
+-end;
+-
+-architecture RTL of M6522 is
+-
+- signal phase : std_logic_vector(1 downto 0);
+- signal p2_h_t1 : std_logic;
+- signal cs : std_logic;
+-
+- -- registers
+- signal r_ddra : std_logic_vector(7 downto 0);
+- signal r_ora : std_logic_vector(7 downto 0);
+- signal r_ira : std_logic_vector(7 downto 0);
+-
+- signal r_ddrb : std_logic_vector(7 downto 0);
+- signal r_orb : std_logic_vector(7 downto 0);
+- signal r_irb : std_logic_vector(7 downto 0);
+-
+- signal r_t1l_l : std_logic_vector(7 downto 0);
+- signal r_t1l_h : std_logic_vector(7 downto 0);
+- signal r_t2l_l : std_logic_vector(7 downto 0);
+- signal r_t2l_h : std_logic_vector(7 downto 0); -- not in real chip
+- signal r_sr : std_logic_vector(7 downto 0);
+- signal r_acr : std_logic_vector(7 downto 0);
+- signal r_pcr : std_logic_vector(7 downto 0);
+- signal r_ifr : std_logic_vector(7 downto 0);
+- signal r_ier : std_logic_vector(6 downto 0);
+-
+- signal sr_write_ena : boolean;
+- signal sr_read_ena : boolean;
+- signal ifr_write_ena : boolean;
+- signal ier_write_ena : boolean;
+- signal clear_irq : std_logic_vector(7 downto 0);
+- signal load_data : std_logic_vector(7 downto 0);
+-
+- -- timer 1
+- signal t1c : std_logic_vector(15 downto 0);
+- signal t1c_active : boolean;
+- signal t1c_done : boolean;
+- signal t1_w_reset_int : boolean;
+- signal t1_r_reset_int : boolean;
+- signal t1_load_counter : boolean;
+- signal t1_reload_counter : boolean;
+- signal t1_toggle : std_logic;
+- signal t1_irq : std_logic := '0';
+-
+- -- timer 2
+- signal t2c : std_logic_vector(15 downto 0);
+- signal t2c_active : boolean;
+- signal t2c_done : boolean;
+- signal t2_pb6 : std_logic;
+- signal t2_pb6_t1 : std_logic;
+- signal t2_w_reset_int : boolean;
+- signal t2_r_reset_int : boolean;
+- signal t2_load_counter : boolean;
+- signal t2_reload_counter : boolean;
+- signal t2_irq : std_logic := '0';
+- signal t2_sr_ena : boolean;
+-
+- -- shift reg
+- signal sr_cnt : std_logic_vector(3 downto 0);
+- signal sr_cb1_oe_l : std_logic;
+- signal sr_cb1_out : std_logic;
+- signal sr_drive_cb2 : std_logic;
+- signal sr_strobe : std_logic;
+- signal sr_strobe_t1 : std_logic;
+- signal sr_strobe_falling : boolean;
+- signal sr_strobe_rising : boolean;
+- signal sr_irq : std_logic;
+- signal sr_out : std_logic;
+- signal sr_off_delay : std_logic;
+-
+- -- io
+- signal w_orb_hs : std_logic;
+- signal w_ora_hs : std_logic;
+- signal r_irb_hs : std_logic;
+- signal r_ira_hs : std_logic;
+-
+- signal ca_hs_sr : std_logic;
+- signal ca_hs_pulse : std_logic;
+- signal cb_hs_sr : std_logic;
+- signal cb_hs_pulse : std_logic;
+-
+- signal cb1_in_mux : std_logic;
+- signal ca1_ip_reg : std_logic;
+- signal cb1_ip_reg : std_logic;
+- signal ca1_int : boolean;
+- signal cb1_int : boolean;
+- signal ca1_irq : std_logic;
+- signal cb1_irq : std_logic;
+-
+- signal ca2_ip_reg : std_logic;
+- signal cb2_ip_reg : std_logic;
+- signal ca2_int : boolean;
+- signal cb2_int : boolean;
+- signal ca2_irq : std_logic;
+- signal cb2_irq : std_logic;
+-
+- signal final_irq : std_logic;
+-begin
+- p_phase : process
+- begin
+- -- internal clock phase
+- wait until rising_edge(CLK);
+- if (ENA_4 = '1') then
+- p2_h_t1 <= I_P2_H;
+- if (p2_h_t1 = '0') and (I_P2_H = '1') then
+- phase <= "11";
+- else
+- phase <= phase + "1";
+- end if;
+- end if;
+- end process;
+-
+- p_cs : process(I_CS1, I_CS2_L, I_P2_H)
+- begin
+- cs <= '0';
+- if (I_CS1 = '1') and (I_CS2_L = '0') and (I_P2_H = '1') then
+- cs <= '1';
+- end if;
+- end process;
+-
+- -- peripheral control reg (pcr)
+- -- 0 ca1 interrupt control (0 +ve edge, 1 -ve edge)
+- -- 3..1 ca2 operation
+- -- 000 input -ve edge
+- -- 001 independend interrupt input -ve edge
+- -- 010 input +ve edge
+- -- 011 independend interrupt input +ve edge
+- -- 100 handshake output
+- -- 101 pulse output
+- -- 110 low output
+- -- 111 high output
+- -- 7..4 as 3..0 for cb1,cb2
+-
+- -- auxiliary control reg (acr)
+- -- 0 input latch PA (0 disable, 1 enable)
+- -- 1 input latch PB (0 disable, 1 enable)
+- -- 4..2 shift reg control
+- -- 000 disable
+- -- 001 shift in using t2
+- -- 010 shift in using o2
+- -- 011 shift in using ext clk
+- -- 100 shift out free running t2 rate
+- -- 101 shift out using t2
+- -- 101 shift out using o2
+- -- 101 shift out using ext clk
+- -- 5 t2 timer control (0 timed interrupt, 1 count down with pulses on pb6)
+- -- 7..6 t1 timer control
+- -- 00 timed interrupt each time t1 is loaded pb7 disable
+- -- 01 continuous interrupts pb7 disable
+- -- 00 timed interrupt each time t1 is loaded pb7 one shot output
+- -- 01 continuous interrupts pb7 square wave output
+- --
+-
+- p_write_reg_reset : process(RESET_L, CLK)
+- begin
+- if (RESET_L = '0') then
+- r_ora <= x"00"; r_orb <= x"00";
+- r_ddra <= x"00"; r_ddrb <= x"00";
+- r_acr <= x"00"; r_pcr <= x"00";
+-
+- w_orb_hs <= '0';
+- w_ora_hs <= '0';
+- elsif rising_edge(CLK) then
+- if (ENA_4 = '1') then
+- w_orb_hs <= '0';
+- w_ora_hs <= '0';
+- if (cs = '1') and (I_RW_L = '0') then
+- case I_RS is
+- when x"0" => r_orb <= I_DATA; w_orb_hs <= '1';
+- when x"1" => r_ora <= I_DATA; w_ora_hs <= '1';
+- when x"2" => r_ddrb <= I_DATA;
+- when x"3" => r_ddra <= I_DATA;
+-
+- when x"B" => r_acr <= I_DATA;
+- when x"C" => r_pcr <= I_DATA;
+- when x"F" => r_ora <= I_DATA;
+-
+- when others => null;
+- end case;
+- end if;
+-
+- if (r_acr(7) = '1') and (t1_toggle = '1') then
+- r_orb(7) <= not r_orb(7); -- toggle
+- end if;
+- end if;
+- end if;
+- end process;
+-
+- p_write_reg : process
+- begin
+- wait until rising_edge(CLK);
+- if (ENA_4 = '1') then
+- t1_w_reset_int <= false;
+- t1_load_counter <= false;
+-
+- t2_w_reset_int <= false;
+- t2_load_counter <= false;
+-
+- load_data <= x"00";
+- sr_write_ena <= false;
+- ifr_write_ena <= false;
+- ier_write_ena <= false;
+-
+- if (cs = '1') and (I_RW_L = '0') then
+- load_data <= I_DATA;
+- case I_RS is
+- when x"4" => r_t1l_l <= I_DATA;
+- when x"5" => r_t1l_h <= I_DATA; t1_w_reset_int <= true;
+- t1_load_counter <= true;
+-
+- when x"6" => r_t1l_l <= I_DATA;
+- when x"7" => r_t1l_h <= I_DATA; t1_w_reset_int <= true;
+-
+- when x"8" => r_t2l_l <= I_DATA;
+- when x"9" => r_t2l_h <= I_DATA; t2_w_reset_int <= true;
+- t2_load_counter <= true;
+-
+- when x"A" => sr_write_ena <= true;
+- when x"D" => ifr_write_ena <= true;
+- when x"E" => ier_write_ena <= true;
+-
+- when others => null;
+- end case;
+- end if;
+- end if;
+- end process;
+-
+- p_oe : process(cs, I_RW_L)
+- begin
+- O_DATA_OE_L <= '1';
+- if (cs = '1') and (I_RW_L = '1') then
+- O_DATA_OE_L <= '0';
+- end if;
+- end process;
+-
+- p_read : process
+- begin
+- wait until rising_edge(CLK);
+-
+- if ENA_4 = '1' then
+- t1_r_reset_int <= false;
+- t2_r_reset_int <= false;
+- sr_read_ena <= false;
+- r_irb_hs <= '0';
+- r_ira_hs <= '0';
+-
+- if (cs = '1') and (I_RW_L = '1') then
+- case I_RS is
+- --when x"0" => O_DATA <= r_irb; r_irb_hs <= '1';
+- -- fix from Mark McDougall, untested
+- when x"0" => O_DATA <= (r_irb and not r_ddrb) or (r_orb and r_ddrb); r_irb_hs <= '1';
+- when x"1" => O_DATA <= r_ira; r_ira_hs <= '1';
+- when x"2" => O_DATA <= r_ddrb;
+- when x"3" => O_DATA <= r_ddra;
+- when x"4" => O_DATA <= t1c( 7 downto 0); t1_r_reset_int <= true;
+- when x"5" => O_DATA <= t1c(15 downto 8);
+- when x"6" => O_DATA <= r_t1l_l;
+- when x"7" => O_DATA <= r_t1l_h;
+- when x"8" => O_DATA <= t2c( 7 downto 0); t2_r_reset_int <= true;
+- when x"9" => O_DATA <= t2c(15 downto 8);
+- when x"A" => O_DATA <= r_sr; sr_read_ena <= true;
+- when x"B" => O_DATA <= r_acr;
+- when x"C" => O_DATA <= r_pcr;
+- when x"D" => O_DATA <= r_ifr;
+- when x"E" => O_DATA <= ('0' & r_ier);
+- when x"F" => O_DATA <= r_ira;
+- when others => null;
+- end case;
+- end if;
+- end if;
+-
+- end process;
+- --
+- -- IO
+- --
+- p_ca1_cb1_sel : process(sr_cb1_oe_l, sr_cb1_out, I_CB1)
+- begin
+- -- if the shift register is enabled, cb1 may be an output
+- -- in this case, we should listen to the CB1_OUT for the interrupt
+- if (sr_cb1_oe_l = '1') then
+- cb1_in_mux <= I_CB1;
+- else
+- cb1_in_mux <= sr_cb1_out;
+- end if;
+- end process;
+-
+- p_ca1_cb1_int : process(r_pcr, ca1_ip_reg, I_CA1, cb1_ip_reg, cb1_in_mux)
+- begin
+- if (r_pcr(0) = '0') then -- ca1 control
+- -- negative edge
+- ca1_int <= (ca1_ip_reg = '1') and (I_CA1 = '0');
+- else
+- -- positive edge
+- ca1_int <= (ca1_ip_reg = '0') and (I_CA1 = '1');
+- end if;
+-
+- if (r_pcr(4) = '0') then -- cb1 control
+- -- negative edge
+- cb1_int <= (cb1_ip_reg = '1') and (cb1_in_mux = '0');
+- else
+- -- positive edge
+- cb1_int <= (cb1_ip_reg = '0') and (cb1_in_mux = '1');
+- end if;
+- end process;
+-
+- p_ca2_cb2_int : process(r_pcr, ca2_ip_reg, I_CA2, cb2_ip_reg, I_CB2)
+- begin
+- ca2_int <= false;
+- if (r_pcr(3) = '0') then -- ca2 input
+- if (r_pcr(2) = '0') then -- ca2 edge
+- -- negative edge
+- ca2_int <= (ca2_ip_reg = '1') and (I_CA2 = '0');
+- else
+- -- positive edge
+- ca2_int <= (ca2_ip_reg = '0') and (I_CA2 = '1');
+- end if;
+- end if;
+-
+- cb2_int <= false;
+- if (r_pcr(7) = '0') then -- cb2 input
+- if (r_pcr(6) = '0') then -- cb2 edge
+- -- negative edge
+- cb2_int <= (cb2_ip_reg = '1') and (I_CB2 = '0');
+- else
+- -- positive edge
+- cb2_int <= (cb2_ip_reg = '0') and (I_CB2 = '1');
+- end if;
+- end if;
+- end process;
+-
+- p_ca2_cb2 : process(RESET_L, CLK)
+- begin
+- if (RESET_L = '0') then
+- O_CA2 <= '0';
+- O_CA2_OE_L <= '1';
+- O_CB2 <= '0';
+- O_CB2_OE_L <= '1';
+-
+- ca_hs_sr <= '0';
+- ca_hs_pulse <= '0';
+- cb_hs_sr <= '0';
+- cb_hs_pulse <= '0';
+- elsif rising_edge(CLK) then
+- if (ENA_4 = '1') then
+- -- ca
+- if (phase = "00") and ((w_ora_hs = '1') or (r_ira_hs = '1')) then
+- ca_hs_sr <= '1';
+- elsif ca1_int then
+- ca_hs_sr <= '0';
+- end if;
+-
+- if (phase = "00") then
+- ca_hs_pulse <= w_ora_hs or r_ira_hs;
+- end if;
+-
+- O_CA2_OE_L <= not r_pcr(3); -- ca2 output
+- case r_pcr(3 downto 1) is
+- when "000" => O_CA2 <= '0'; -- input
+- when "001" => O_CA2 <= '0'; -- input
+- when "010" => O_CA2 <= '0'; -- input
+- when "011" => O_CA2 <= '0'; -- input
+- when "100" => O_CA2 <= not (ca_hs_sr); -- handshake
+- when "101" => O_CA2 <= not (ca_hs_pulse); -- pulse
+- when "110" => O_CA2 <= '0'; -- low
+- when "111" => O_CA2 <= '1'; -- high
+- when others => null;
+- end case;
+-
+- -- cb
+- if (phase = "00") and (w_orb_hs = '1') then
+- cb_hs_sr <= '1';
+- elsif cb1_int then
+- cb_hs_sr <= '0';
+- end if;
+-
+- if (phase = "00") then
+- cb_hs_pulse <= w_orb_hs;
+- end if;
+-
+- O_CB2_OE_L <= not (r_pcr(7) or sr_drive_cb2); -- cb2 output or serial
+- if (sr_drive_cb2 = '1') then -- serial output
+- O_CB2 <= sr_out;
+- else
+- case r_pcr(7 downto 5) is
+- when "000" => O_CB2 <= '0'; -- input
+- when "001" => O_CB2 <= '0'; -- input
+- when "010" => O_CB2 <= '0'; -- input
+- when "011" => O_CB2 <= '0'; -- input
+- when "100" => O_CB2 <= not (cb_hs_sr); -- handshake
+- when "101" => O_CB2 <= not (cb_hs_pulse); -- pulse
+- when "110" => O_CB2 <= '0'; -- low
+- when "111" => O_CB2 <= '1'; -- high
+- when others => null;
+- end case;
+- end if;
+- end if;
+- end if;
+- end process;
+- O_CB1 <= sr_cb1_out;
+- O_CB1_OE_L <= sr_cb1_oe_l;
+-
+- p_ca_cb_irq : process(RESET_L, CLK)
+- begin
+- if (RESET_L = '0') then
+- ca1_irq <= '0';
+- ca2_irq <= '0';
+- cb1_irq <= '0';
+- cb2_irq <= '0';
+- elsif rising_edge(CLK) then
+- if (ENA_4 = '1') then
+- -- not pretty
+- if ca1_int then
+- ca1_irq <= '1';
+- elsif (r_ira_hs = '1') or (w_ora_hs = '1') or (clear_irq(1) = '1') then
+- ca1_irq <= '0';
+- end if;
+-
+- if ca2_int then
+- ca2_irq <= '1';
+- else
+- if (((r_ira_hs = '1') or (w_ora_hs = '1')) and (r_pcr(1) = '0')) or
+- (clear_irq(0) = '1') then
+- ca2_irq <= '0';
+- end if;
+- end if;
+-
+- if cb1_int then
+- cb1_irq <= '1';
+- elsif (r_irb_hs = '1') or (w_orb_hs = '1') or (clear_irq(4) = '1') then
+- cb1_irq <= '0';
+- end if;
+-
+- if cb2_int then
+- cb2_irq <= '1';
+- else
+- if (((r_irb_hs = '1') or (w_orb_hs = '1')) and (r_pcr(5) = '0')) or
+- (clear_irq(3) = '1') then
+- cb2_irq <= '0';
+- end if;
+- end if;
+- end if;
+- end if;
+- end process;
+-
+- p_input_reg : process(RESET_L, CLK)
+- begin
+- if (RESET_L = '0') then
+- ca1_ip_reg <= '0';
+- cb1_ip_reg <= '0';
+-
+- ca2_ip_reg <= '0';
+- cb2_ip_reg <= '0';
+-
+- r_ira <= x"00";
+- r_irb <= x"00";
+-
+- elsif rising_edge(CLK) then
+- if (ENA_4 = '1') then
+- -- we have a fast clock, so we can have input registers
+- ca1_ip_reg <= I_CA1;
+- cb1_ip_reg <= cb1_in_mux;
+-
+- ca2_ip_reg <= I_CA2;
+- cb2_ip_reg <= I_CB2;
+-
+- if (r_acr(0) = '0') then
+- r_ira <= I_PA;
+- else -- enable latching
+- if ca1_int then
+- r_ira <= I_PA;
+- end if;
+- end if;
+-
+- if (r_acr(1) = '0') then
+- r_irb <= I_PB;
+- else -- enable latching
+- if cb1_int then
+- r_irb <= I_PB;
+- end if;
+- end if;
+- end if;
+- end if;
+- end process;
+-
+-
+- p_buffers : process(r_ddra, r_ora, r_ddrb, r_acr, r_orb)
+- begin
+- -- data direction reg (ddr) 0 = input, 1 = output
+- O_PA <= r_ora;
+- O_PA_OE_L <= not r_ddra;
+-
+- if (r_acr(7) = '1') then -- not clear if r_ddrb(7) must be 1 as well
+- O_PB_OE_L(7) <= '0'; -- an output if under t1 control
+- else
+- O_PB_OE_L(7) <= not (r_ddrb(7));
+- end if;
+-
+- O_PB_OE_L(6 downto 0) <= not r_ddrb(6 downto 0);
+- O_PB(7 downto 0) <= r_orb(7 downto 0);
+-
+- end process;
+- --
+- -- Timer 1
+- --
+- p_timer1_done : process(t1c,phase,r_acr)
+- variable done : boolean;
+- begin
+- done := (t1c = x"0000");
+- t1c_done <= done and (phase = "11");
+- --if (phase = "11") then
+- t1_reload_counter <= done and (r_acr(6) = '1');
+- --end if;
+- end process;
+-
+- p_timer1 : process
+- begin
+- wait until rising_edge(CLK);
+- if (ENA_4 = '1') then
+- if t1_load_counter or (t1_reload_counter and phase = "11") then
+- t1c( 7 downto 0) <= r_t1l_l;
+- t1c(15 downto 8) <= r_t1l_h;
+- elsif (phase="11") then
+- t1c <= t1c - "1";
+- end if;
+-
+- if t1_load_counter or t1_reload_counter then
+- t1c_active <= true;
+- elsif t1c_done then
+- t1c_active <= false;
+- end if;
+- if RESET_L = '0' then
+- t1c_active <= false;
+- end if;
+-
+- t1_toggle <= '0';
+- if t1c_active and t1c_done then
+- t1_toggle <= '1';
+- t1_irq <= '1';
+- elsif RESET_L = '0' or t1_w_reset_int or t1_r_reset_int or (clear_irq(6) = '1') then
+- t1_irq <= '0';
+- end if;
+- end if;
+- end process;
+- --
+- -- Timer2
+- --
+- p_timer2_pb6_input : process
+- begin
+- wait until rising_edge(CLK);
+- if (ENA_4 = '1') then
+- if (phase = "01") then -- leading edge p2_h
+- t2_pb6 <= I_PB(6);
+- t2_pb6_t1 <= t2_pb6;
+- end if;
+- end if;
+- end process;
+-
+- p_timer2_done : process(t2c,phase)
+- variable done : boolean;
+- begin
+- done := (t2c = x"0000");
+- t2c_done <= done and (phase = "11");
+- --if (phase = "11") then
+- t2_reload_counter <= done;
+- --end if;
+- end process;
+-
+- p_timer2 : process
+- variable ena : boolean;
+- begin
+- wait until rising_edge(CLK);
+- if (ENA_4 = '1') then
+- if (r_acr(5) = '0') then
+- ena := true;
+- else
+- ena := (t2_pb6_t1 = '1') and (t2_pb6 = '0'); -- falling edge
+- end if;
+-
+- if t2_load_counter or (t2_reload_counter and phase = "11") then
+- -- not sure if t2c_reload should be here. Does timer2 just continue to
+- -- count down, or is it reloaded ? Reloaded makes more sense if using
+- -- it to generate a clock for the shift register.
+- t2c( 7 downto 0) <= r_t2l_l;
+- t2c(15 downto 8) <= r_t2l_h;
+- else
+- if (phase="11") and ena then -- or count mode
+- t2c <= t2c - "1";
+- end if;
+- end if;
+-
+- t2_sr_ena <= (t2c(7 downto 0) = x"00") and (phase = "11");
+-
+- if t2_load_counter then
+- t2c_active <= true;
+- elsif t2c_done then
+- t2c_active <= false;
+- end if;
+- if RESET_L = '0' then
+- t2c_active <= false;
+- end if;
+-
+- if t2c_active and t2c_done then
+- t2_irq <= '1';
+- elsif RESET_L = '0' or t2_w_reset_int or t2_r_reset_int or (clear_irq(5) = '1') then
+- t2_irq <= '0';
+- end if;
+- end if;
+- end process;
+- --
+- -- Shift Register
+- --
+- p_sr : process(RESET_L, CLK)
+- variable dir_out : std_logic;
+- variable ena : std_logic;
+- variable cb1_op : std_logic;
+- variable cb1_ip : std_logic;
+- variable use_t2 : std_logic;
+- variable free_run : std_logic;
+- variable sr_count_ena : boolean;
+- begin
+- if (RESET_L = '0') then
+- r_sr <= x"00";
+- sr_drive_cb2 <= '0';
+- sr_cb1_oe_l <= '1';
+- sr_cb1_out <= '0';
+- sr_strobe <= '1';
+- sr_cnt <= "0000";
+- sr_irq <= '0';
+- sr_out <= '1';
+- sr_off_delay <= '0';
+- elsif rising_edge(CLK) then
+- if (ENA_4 = '1') then
+- -- decode mode
+- dir_out := r_acr(4); -- output on cb2
+- cb1_op := '0';
+- cb1_ip := '0';
+- use_t2 := '0';
+- free_run := '0';
+-
+- case r_acr(4 downto 2) is
+- when "000" => ena := '0'; cb1_ip := '1';
+- when "001" => ena := '1'; cb1_op := '1'; use_t2 := '1';
+- when "010" => ena := '1'; cb1_op := '1';
+- when "011" => ena := '1'; cb1_ip := '1';
+- when "100" => ena := '1'; use_t2 := '1'; free_run := '1';
+- when "101" => ena := '1'; cb1_op := '1'; use_t2 := '1';
+- when "110" => ena := '1';
+- when "111" => ena := '1'; cb1_ip := '1';
+- when others => null;
+- end case;
+-
+- -- clock select
+- -- SR still runs even in disabled mode (on rising edge of CB1). It
+- -- just doesn't generate any interrupts.
+- -- Ref BBC micro advanced user guide p409
+- if (cb1_ip = '1') then
+- sr_strobe <= I_CB1;
+- else
+- if (sr_cnt(3) = '0') and (free_run = '0') then
+- sr_strobe <= '1';
+- else
+- if ((use_t2 = '1') and t2_sr_ena) or
+- ((use_t2 = '0') and (phase = "00")) then
+- sr_strobe <= not sr_strobe;
+- end if;
+- end if;
+- end if;
+-
+- -- latch on rising edge, shift on falling edge
+- if sr_write_ena then
+- r_sr <= load_data;
+- else
+- if (dir_out = '0') then
+- -- input
+- if (sr_cnt(3) = '1') or (cb1_ip = '1') then
+- if sr_strobe_rising then
+- r_sr <= r_sr(6 downto 0) & I_CB2;
+- end if;
+- end if;
+- sr_out <= '1';
+- else
+- -- output
+- if (sr_cnt(3) = '1') or (sr_off_delay = '1') or (cb1_ip = '1') or (free_run = '1') then
+- if sr_strobe_falling then
+- r_sr(7 downto 1) <= r_sr(6 downto 0);
+- r_sr(0) <= r_sr(7);
+- sr_out <= r_sr(7);
+- end if;
+- else
+- sr_out <= '1';
+- end if;
+- end if;
+- end if;
+-
+- sr_count_ena := sr_strobe_rising;
+-
+- if sr_write_ena or sr_read_ena then
+- -- some documentation says sr bit in IFR must be set as well ?
+- sr_cnt <= "1000";
+- elsif sr_count_ena and (sr_cnt(3) = '1') then
+- sr_cnt <= sr_cnt + "1";
+- end if;
+-
+- if (phase = "00") then
+- sr_off_delay <= sr_cnt(3); -- give some hold time when shifting out
+- end if;
+-
+- if sr_count_ena and (sr_cnt = "1111") and (ena = '1') and (free_run = '0') then
+- sr_irq <= '1';
+- elsif sr_write_ena or sr_read_ena or (clear_irq(2) = '1') then
+- sr_irq <= '0';
+- end if;
+-
+- -- assign ops
+- sr_drive_cb2 <= dir_out;
+- sr_cb1_oe_l <= not cb1_op;
+- sr_cb1_out <= sr_strobe;
+- end if;
+- end if;
+- end process;
+-
+- p_sr_strobe_rise_fall : process
+- begin
+- wait until rising_edge(CLK);
+- if (ENA_4 = '1') then
+- sr_strobe_t1 <= sr_strobe;
+- sr_strobe_rising <= (sr_strobe_t1 = '0') and (sr_strobe = '1');
+- sr_strobe_falling <= (sr_strobe_t1 = '1') and (sr_strobe = '0');
+- end if;
+- end process;
+- --
+- -- Interrupts
+- --
+- p_ier : process(RESET_L, CLK)
+- begin
+- if (RESET_L = '0') then
+- r_ier <= "0000000";
+- elsif rising_edge(CLK) then
+- if (ENA_4 = '1') then
+- if ier_write_ena then
+- if (load_data(7) = '1') then
+- -- set
+- r_ier <= r_ier or load_data(6 downto 0);
+- else
+- -- clear
+- r_ier <= r_ier and not load_data(6 downto 0);
+- end if;
+- end if;
+- end if;
+- end if;
+- end process;
+-
+- p_ifr : process(t1_irq, t2_irq, final_irq, ca1_irq, ca2_irq, sr_irq,
+- cb1_irq, cb2_irq)
+- begin
+- r_ifr(7) <= final_irq;
+- r_ifr(6) <= t1_irq;
+- r_ifr(5) <= t2_irq;
+- r_ifr(4) <= cb1_irq;
+- r_ifr(3) <= cb2_irq;
+- r_ifr(2) <= sr_irq;
+- r_ifr(1) <= ca1_irq;
+- r_ifr(0) <= ca2_irq;
+-
+- O_IRQ_L <= not final_irq;
+- end process;
+-
+- p_irq : process(RESET_L, CLK)
+- begin
+- if (RESET_L = '0') then
+- final_irq <= '0';
+- elsif rising_edge(CLK) then
+- if (ENA_4 = '1') then
+- if ((r_ifr(6 downto 0) and r_ier(6 downto 0)) = "0000000") then
+- final_irq <= '0'; -- no interrupts
+- else
+- final_irq <= '1';
+- end if;
+- end if;
+- end if;
+- end process;
+-
+- p_clear_irq : process(ifr_write_ena, load_data)
+- begin
+- clear_irq <= x"00";
+- if ifr_write_ena then
+- clear_irq <= load_data;
+- end if;
+- end process;
+-
+-end architecture RTL;
++--
++-- A simulation model of VIC20 hardware
++-- Copyright (c) MikeJ - March 2003
++--
++-- 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 CODE 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.
++--
++-- You are responsible for any legal issues arising from your use of this code.
++--
++-- The latest version of this file can be found at: www.fpgaarcade.com
++--
++-- Email vic20@fpgaarcade.com
++--
++--
++-- Revision list
++--
++-- version 002 fix from Mark McDougall, untested
++-- version 001 initial release
++-- not very sure about the shift register, documentation is a bit light.
++
++library ieee ;
++ use ieee.std_logic_1164.all ;
++ use ieee.std_logic_unsigned.all;
++ use ieee.numeric_std.all;
++
++--library UNISIM;
++-- use UNISIM.Vcomponents.all;
++
++entity M6522 is
++ port (
++
++ I_RS : in std_logic_vector(3 downto 0);
++ I_DATA : in std_logic_vector(7 downto 0);
++ O_DATA : out std_logic_vector(7 downto 0);
++ O_DATA_OE_L : out std_logic;
++
++ I_RW_L : in std_logic;
++ I_CS1 : in std_logic;
++ I_CS2_L : in std_logic;
++
++ O_IRQ_L : out std_logic; -- note, not open drain
++ -- port a
++ I_CA1 : in std_logic;
++ I_CA2 : in std_logic;
++ O_CA2 : out std_logic;
++ O_CA2_OE_L : out std_logic;
++
++ I_PA : in std_logic_vector(7 downto 0);
++ O_PA : out std_logic_vector(7 downto 0);
++ O_PA_OE_L : out std_logic_vector(7 downto 0);
++
++ -- port b
++ I_CB1 : in std_logic;
++ O_CB1 : out std_logic;
++ O_CB1_OE_L : out std_logic;
++
++ I_CB2 : in std_logic;
++ O_CB2 : out std_logic;
++ O_CB2_OE_L : out std_logic;
++
++ I_PB : in std_logic_vector(7 downto 0);
++ O_PB : out std_logic_vector(7 downto 0);
++ O_PB_OE_L : out std_logic_vector(7 downto 0);
++
++ I_P2_H : in std_logic; -- high for phase 2 clock ____----__
++ RESET_L : in std_logic;
++ ENA_4 : in std_logic; -- clk enable
++ CLK : in std_logic
++ );
++end;
++
++architecture RTL of M6522 is
++
++ signal phase : std_logic_vector(1 downto 0);
++ signal p2_h_t1 : std_logic;
++ signal cs : std_logic;
++
++ -- registers
++ signal r_ddra : std_logic_vector(7 downto 0);
++ signal r_ora : std_logic_vector(7 downto 0);
++ signal r_ira : std_logic_vector(7 downto 0);
++
++ signal r_ddrb : std_logic_vector(7 downto 0);
++ signal r_orb : std_logic_vector(7 downto 0);
++ signal r_irb : std_logic_vector(7 downto 0);
++
++ signal r_t1l_l : std_logic_vector(7 downto 0);
++ signal r_t1l_h : std_logic_vector(7 downto 0);
++ signal r_t2l_l : std_logic_vector(7 downto 0);
++ signal r_t2l_h : std_logic_vector(7 downto 0); -- not in real chip
++ signal r_sr : std_logic_vector(7 downto 0);
++ signal r_acr : std_logic_vector(7 downto 0);
++ signal r_pcr : std_logic_vector(7 downto 0);
++ signal r_ifr : std_logic_vector(7 downto 0);
++ signal r_ier : std_logic_vector(6 downto 0);
++
++ signal sr_write_ena : boolean;
++ signal sr_read_ena : boolean;
++ signal ifr_write_ena : boolean;
++ signal ier_write_ena : boolean;
++ signal clear_irq : std_logic_vector(7 downto 0);
++ signal load_data : std_logic_vector(7 downto 0);
++
++ -- timer 1
++ signal t1c : std_logic_vector(15 downto 0);
++ signal t1c_active : boolean;
++ signal t1c_done : boolean;
++ signal t1_w_reset_int : boolean;
++ signal t1_r_reset_int : boolean;
++ signal t1_load_counter : boolean;
++ signal t1_reload_counter : boolean;
++ signal t1_toggle : std_logic;
++ signal t1_irq : std_logic := '0';
++
++ -- timer 2
++ signal t2c : std_logic_vector(15 downto 0);
++ signal t2c_active : boolean;
++ signal t2c_done : boolean;
++ signal t2_pb6 : std_logic;
++ signal t2_pb6_t1 : std_logic;
++ signal t2_w_reset_int : boolean;
++ signal t2_r_reset_int : boolean;
++ signal t2_load_counter : boolean;
++ signal t2_reload_counter : boolean;
++ signal t2_irq : std_logic := '0';
++ signal t2_sr_ena : boolean;
++
++ -- shift reg
++ signal sr_cnt : std_logic_vector(3 downto 0);
++ signal sr_cb1_oe_l : std_logic;
++ signal sr_cb1_out : std_logic;
++ signal sr_drive_cb2 : std_logic;
++ signal sr_strobe : std_logic;
++ signal sr_strobe_t1 : std_logic;
++ signal sr_strobe_falling : boolean;
++ signal sr_strobe_rising : boolean;
++ signal sr_irq : std_logic;
++ signal sr_out : std_logic;
++ signal sr_off_delay : std_logic;
++
++ -- io
++ signal w_orb_hs : std_logic;
++ signal w_ora_hs : std_logic;
++ signal r_irb_hs : std_logic;
++ signal r_ira_hs : std_logic;
++
++ signal ca_hs_sr : std_logic;
++ signal ca_hs_pulse : std_logic;
++ signal cb_hs_sr : std_logic;
++ signal cb_hs_pulse : std_logic;
++
++ signal cb1_in_mux : std_logic;
++ signal ca1_ip_reg : std_logic;
++ signal cb1_ip_reg : std_logic;
++ signal ca1_int : boolean;
++ signal cb1_int : boolean;
++ signal ca1_irq : std_logic;
++ signal cb1_irq : std_logic;
++
++ signal ca2_ip_reg : std_logic;
++ signal cb2_ip_reg : std_logic;
++ signal ca2_int : boolean;
++ signal cb2_int : boolean;
++ signal ca2_irq : std_logic;
++ signal cb2_irq : std_logic;
++
++ signal final_irq : std_logic;
++begin
++ p_phase : process
++ begin
++ -- internal clock phase
++ wait until rising_edge(CLK);
++ if (ENA_4 = '1') then
++ p2_h_t1 <= I_P2_H;
++ if (p2_h_t1 = '0') and (I_P2_H = '1') then
++ phase <= "11";
++ else
++ phase <= phase + "1";
++ end if;
++ end if;
++ end process;
++
++ p_cs : process(I_CS1, I_CS2_L, I_P2_H)
++ begin
++ cs <= '0';
++ if (I_CS1 = '1') and (I_CS2_L = '0') and (I_P2_H = '1') then
++ cs <= '1';
++ end if;
++ end process;
++
++ -- peripheral control reg (pcr)
++ -- 0 ca1 interrupt control (0 +ve edge, 1 -ve edge)
++ -- 3..1 ca2 operation
++ -- 000 input -ve edge
++ -- 001 independend interrupt input -ve edge
++ -- 010 input +ve edge
++ -- 011 independend interrupt input +ve edge
++ -- 100 handshake output
++ -- 101 pulse output
++ -- 110 low output
++ -- 111 high output
++ -- 7..4 as 3..0 for cb1,cb2
++
++ -- auxiliary control reg (acr)
++ -- 0 input latch PA (0 disable, 1 enable)
++ -- 1 input latch PB (0 disable, 1 enable)
++ -- 4..2 shift reg control
++ -- 000 disable
++ -- 001 shift in using t2
++ -- 010 shift in using o2
++ -- 011 shift in using ext clk
++ -- 100 shift out free running t2 rate
++ -- 101 shift out using t2
++ -- 101 shift out using o2
++ -- 101 shift out using ext clk
++ -- 5 t2 timer control (0 timed interrupt, 1 count down with pulses on pb6)
++ -- 7..6 t1 timer control
++ -- 00 timed interrupt each time t1 is loaded pb7 disable
++ -- 01 continuous interrupts pb7 disable
++ -- 00 timed interrupt each time t1 is loaded pb7 one shot output
++ -- 01 continuous interrupts pb7 square wave output
++ --
++
++ p_write_reg_reset : process(RESET_L, CLK)
++ begin
++ if (RESET_L = '0') then
++ r_ora <= x"00"; r_orb <= x"00";
++ r_ddra <= x"00"; r_ddrb <= x"00";
++ r_acr <= x"00"; r_pcr <= x"00";
++
++ w_orb_hs <= '0';
++ w_ora_hs <= '0';
++ elsif rising_edge(CLK) then
++ if (ENA_4 = '1') then
++ w_orb_hs <= '0';
++ w_ora_hs <= '0';
++ if (cs = '1') and (I_RW_L = '0') then
++ case I_RS is
++ when x"0" => r_orb <= I_DATA; w_orb_hs <= '1';
++ when x"1" => r_ora <= I_DATA; w_ora_hs <= '1';
++ when x"2" => r_ddrb <= I_DATA;
++ when x"3" => r_ddra <= I_DATA;
++
++ when x"B" => r_acr <= I_DATA;
++ when x"C" => r_pcr <= I_DATA;
++ when x"F" => r_ora <= I_DATA;
++
++ when others => null;
++ end case;
++ end if;
++
++ if (r_acr(7) = '1') and (t1_toggle = '1') then
++ r_orb(7) <= not r_orb(7); -- toggle
++ end if;
++ end if;
++ end if;
++ end process;
++
++ p_write_reg : process
++ begin
++ wait until rising_edge(CLK);
++ if (ENA_4 = '1') then
++ t1_w_reset_int <= false;
++ t1_load_counter <= false;
++
++ t2_w_reset_int <= false;
++ t2_load_counter <= false;
++
++ load_data <= x"00";
++ sr_write_ena <= false;
++ ifr_write_ena <= false;
++ ier_write_ena <= false;
++
++ if (cs = '1') and (I_RW_L = '0') then
++ load_data <= I_DATA;
++ case I_RS is
++ when x"4" => r_t1l_l <= I_DATA;
++ when x"5" => r_t1l_h <= I_DATA; t1_w_reset_int <= true;
++ t1_load_counter <= true;
++
++ when x"6" => r_t1l_l <= I_DATA;
++ when x"7" => r_t1l_h <= I_DATA; t1_w_reset_int <= true;
++
++ when x"8" => r_t2l_l <= I_DATA;
++ when x"9" => r_t2l_h <= I_DATA; t2_w_reset_int <= true;
++ t2_load_counter <= true;
++
++ when x"A" => sr_write_ena <= true;
++ when x"D" => ifr_write_ena <= true;
++ when x"E" => ier_write_ena <= true;
++
++ when others => null;
++ end case;
++ end if;
++ end if;
++ end process;
++
++ p_oe : process(cs, I_RW_L)
++ begin
++ O_DATA_OE_L <= '1';
++ if (cs = '1') and (I_RW_L = '1') then
++ O_DATA_OE_L <= '0';
++ end if;
++ end process;
++
++ p_read : process
++ begin
++ wait until rising_edge(CLK);
++
++ if ENA_4 = '1' then
++ t1_r_reset_int <= false;
++ t2_r_reset_int <= false;
++ sr_read_ena <= false;
++ r_irb_hs <= '0';
++ r_ira_hs <= '0';
++
++ if (cs = '1') and (I_RW_L = '1') then
++ case I_RS is
++ --when x"0" => O_DATA <= r_irb; r_irb_hs <= '1';
++ -- fix from Mark McDougall, untested
++ when x"0" => O_DATA <= (r_irb and not r_ddrb) or (r_orb and r_ddrb); r_irb_hs <= '1';
++ when x"1" => O_DATA <= r_ira; r_ira_hs <= '1';
++ when x"2" => O_DATA <= r_ddrb;
++ when x"3" => O_DATA <= r_ddra;
++ when x"4" => O_DATA <= t1c( 7 downto 0); t1_r_reset_int <= true;
++ when x"5" => O_DATA <= t1c(15 downto 8);
++ when x"6" => O_DATA <= r_t1l_l;
++ when x"7" => O_DATA <= r_t1l_h;
++ when x"8" => O_DATA <= t2c( 7 downto 0); t2_r_reset_int <= true;
++ when x"9" => O_DATA <= t2c(15 downto 8);
++ when x"A" => O_DATA <= r_sr; sr_read_ena <= true;
++ when x"B" => O_DATA <= r_acr;
++ when x"C" => O_DATA <= r_pcr;
++ when x"D" => O_DATA <= r_ifr;
++ when x"E" => O_DATA <= ('0' & r_ier);
++ when x"F" => O_DATA <= r_ira;
++ when others => null;
++ end case;
++ end if;
++ end if;
++
++ end process;
++ --
++ -- IO
++ --
++ p_ca1_cb1_sel : process(sr_cb1_oe_l, sr_cb1_out, I_CB1)
++ begin
++ -- if the shift register is enabled, cb1 may be an output
++ -- in this case, we should listen to the CB1_OUT for the interrupt
++ if (sr_cb1_oe_l = '1') then
++ cb1_in_mux <= I_CB1;
++ else
++ cb1_in_mux <= sr_cb1_out;
++ end if;
++ end process;
++
++ p_ca1_cb1_int : process(r_pcr, ca1_ip_reg, I_CA1, cb1_ip_reg, cb1_in_mux)
++ begin
++ if (r_pcr(0) = '0') then -- ca1 control
++ -- negative edge
++ ca1_int <= (ca1_ip_reg = '1') and (I_CA1 = '0');
++ else
++ -- positive edge
++ ca1_int <= (ca1_ip_reg = '0') and (I_CA1 = '1');
++ end if;
++
++ if (r_pcr(4) = '0') then -- cb1 control
++ -- negative edge
++ cb1_int <= (cb1_ip_reg = '1') and (cb1_in_mux = '0');
++ else
++ -- positive edge
++ cb1_int <= (cb1_ip_reg = '0') and (cb1_in_mux = '1');
++ end if;
++ end process;
++
++ p_ca2_cb2_int : process(r_pcr, ca2_ip_reg, I_CA2, cb2_ip_reg, I_CB2)
++ begin
++ ca2_int <= false;
++ if (r_pcr(3) = '0') then -- ca2 input
++ if (r_pcr(2) = '0') then -- ca2 edge
++ -- negative edge
++ ca2_int <= (ca2_ip_reg = '1') and (I_CA2 = '0');
++ else
++ -- positive edge
++ ca2_int <= (ca2_ip_reg = '0') and (I_CA2 = '1');
++ end if;
++ end if;
++
++ cb2_int <= false;
++ if (r_pcr(7) = '0') then -- cb2 input
++ if (r_pcr(6) = '0') then -- cb2 edge
++ -- negative edge
++ cb2_int <= (cb2_ip_reg = '1') and (I_CB2 = '0');
++ else
++ -- positive edge
++ cb2_int <= (cb2_ip_reg = '0') and (I_CB2 = '1');
++ end if;
++ end if;
++ end process;
++
++ p_ca2_cb2 : process(RESET_L, CLK)
++ begin
++ if (RESET_L = '0') then
++ O_CA2 <= '0';
++ O_CA2_OE_L <= '1';
++ O_CB2 <= '0';
++ O_CB2_OE_L <= '1';
++
++ ca_hs_sr <= '0';
++ ca_hs_pulse <= '0';
++ cb_hs_sr <= '0';
++ cb_hs_pulse <= '0';
++ elsif rising_edge(CLK) then
++ if (ENA_4 = '1') then
++ -- ca
++ if (phase = "00") and ((w_ora_hs = '1') or (r_ira_hs = '1')) then
++ ca_hs_sr <= '1';
++ elsif ca1_int then
++ ca_hs_sr <= '0';
++ end if;
++
++ if (phase = "00") then
++ ca_hs_pulse <= w_ora_hs or r_ira_hs;
++ end if;
++
++ O_CA2_OE_L <= not r_pcr(3); -- ca2 output
++ case r_pcr(3 downto 1) is
++ when "000" => O_CA2 <= '0'; -- input
++ when "001" => O_CA2 <= '0'; -- input
++ when "010" => O_CA2 <= '0'; -- input
++ when "011" => O_CA2 <= '0'; -- input
++ when "100" => O_CA2 <= not (ca_hs_sr); -- handshake
++ when "101" => O_CA2 <= not (ca_hs_pulse); -- pulse
++ when "110" => O_CA2 <= '0'; -- low
++ when "111" => O_CA2 <= '1'; -- high
++ when others => null;
++ end case;
++
++ -- cb
++ if (phase = "00") and (w_orb_hs = '1') then
++ cb_hs_sr <= '1';
++ elsif cb1_int then
++ cb_hs_sr <= '0';
++ end if;
++
++ if (phase = "00") then
++ cb_hs_pulse <= w_orb_hs;
++ end if;
++
++ O_CB2_OE_L <= not (r_pcr(7) or sr_drive_cb2); -- cb2 output or serial
++ if (sr_drive_cb2 = '1') then -- serial output
++ O_CB2 <= sr_out;
++ else
++ case r_pcr(7 downto 5) is
++ when "000" => O_CB2 <= '0'; -- input
++ when "001" => O_CB2 <= '0'; -- input
++ when "010" => O_CB2 <= '0'; -- input
++ when "011" => O_CB2 <= '0'; -- input
++ when "100" => O_CB2 <= not (cb_hs_sr); -- handshake
++ when "101" => O_CB2 <= not (cb_hs_pulse); -- pulse
++ when "110" => O_CB2 <= '0'; -- low
++ when "111" => O_CB2 <= '1'; -- high
++ when others => null;
++ end case;
++ end if;
++ end if;
++ end if;
++ end process;
++ O_CB1 <= sr_cb1_out;
++ O_CB1_OE_L <= sr_cb1_oe_l;
++
++ p_ca_cb_irq : process(RESET_L, CLK)
++ begin
++ if (RESET_L = '0') then
++ ca1_irq <= '0';
++ ca2_irq <= '0';
++ cb1_irq <= '0';
++ cb2_irq <= '0';
++ elsif rising_edge(CLK) then
++ if (ENA_4 = '1') then
++ -- not pretty
++ if ca1_int then
++ ca1_irq <= '1';
++ elsif (r_ira_hs = '1') or (w_ora_hs = '1') or (clear_irq(1) = '1') then
++ ca1_irq <= '0';
++ end if;
++
++ if ca2_int then
++ ca2_irq <= '1';
++ else
++ if (((r_ira_hs = '1') or (w_ora_hs = '1')) and (r_pcr(1) = '0')) or
++ (clear_irq(0) = '1') then
++ ca2_irq <= '0';
++ end if;
++ end if;
++
++ if cb1_int then
++ cb1_irq <= '1';
++ elsif (r_irb_hs = '1') or (w_orb_hs = '1') or (clear_irq(4) = '1') then
++ cb1_irq <= '0';
++ end if;
++
++ if cb2_int then
++ cb2_irq <= '1';
++ else
++ if (((r_irb_hs = '1') or (w_orb_hs = '1')) and (r_pcr(5) = '0')) or
++ (clear_irq(3) = '1') then
++ cb2_irq <= '0';
++ end if;
++ end if;
++ end if;
++ end if;
++ end process;
++
++ p_input_reg : process(RESET_L, CLK)
++ begin
++ if (RESET_L = '0') then
++ ca1_ip_reg <= '0';
++ cb1_ip_reg <= '0';
++
++ ca2_ip_reg <= '0';
++ cb2_ip_reg <= '0';
++
++ r_ira <= x"00";
++ r_irb <= x"00";
++
++ elsif rising_edge(CLK) then
++ if (ENA_4 = '1') then
++ -- we have a fast clock, so we can have input registers
++ ca1_ip_reg <= I_CA1;
++ cb1_ip_reg <= cb1_in_mux;
++
++ ca2_ip_reg <= I_CA2;
++ cb2_ip_reg <= I_CB2;
++
++ if (r_acr(0) = '0') then
++ r_ira <= I_PA;
++ else -- enable latching
++ if ca1_int then
++ r_ira <= I_PA;
++ end if;
++ end if;
++
++ if (r_acr(1) = '0') then
++ r_irb <= I_PB;
++ else -- enable latching
++ if cb1_int then
++ r_irb <= I_PB;
++ end if;
++ end if;
++ end if;
++ end if;
++ end process;
++
++
++ p_buffers : process(r_ddra, r_ora, r_ddrb, r_acr, r_orb)
++ begin
++ -- data direction reg (ddr) 0 = input, 1 = output
++ O_PA <= r_ora;
++ O_PA_OE_L <= not r_ddra;
++
++ if (r_acr(7) = '1') then -- not clear if r_ddrb(7) must be 1 as well
++ O_PB_OE_L(7) <= '0'; -- an output if under t1 control
++ else
++ O_PB_OE_L(7) <= not (r_ddrb(7));
++ end if;
++
++ O_PB_OE_L(6 downto 0) <= not r_ddrb(6 downto 0);
++ O_PB(7 downto 0) <= r_orb(7 downto 0);
++
++ end process;
++ --
++ -- Timer 1
++ --
++ p_timer1_done : process(t1c,phase,r_acr)
++ variable done : boolean;
++ begin
++ done := (t1c = x"0000");
++ t1c_done <= done and (phase = "11");
++ --if (phase = "11") then
++ t1_reload_counter <= done and (r_acr(6) = '1');
++ --end if;
++ end process;
++
++ p_timer1 : process
++ begin
++ wait until rising_edge(CLK);
++ if (ENA_4 = '1') then
++ if t1_load_counter or (t1_reload_counter and phase = "11") then
++ t1c( 7 downto 0) <= r_t1l_l;
++ t1c(15 downto 8) <= r_t1l_h;
++ elsif (phase="11") then
++ t1c <= t1c - "1";
++ end if;
++
++ if t1_load_counter or t1_reload_counter then
++ t1c_active <= true;
++ elsif t1c_done then
++ t1c_active <= false;
++ end if;
++ if RESET_L = '0' then
++ t1c_active <= false;
++ end if;
++
++ t1_toggle <= '0';
++ if t1c_active and t1c_done then
++ t1_toggle <= '1';
++ t1_irq <= '1';
++ elsif RESET_L = '0' or t1_w_reset_int or t1_r_reset_int or (clear_irq(6) = '1') then
++ t1_irq <= '0';
++ end if;
++ end if;
++ end process;
++ --
++ -- Timer2
++ --
++ p_timer2_pb6_input : process
++ begin
++ wait until rising_edge(CLK);
++ if (ENA_4 = '1') then
++ if (phase = "01") then -- leading edge p2_h
++ t2_pb6 <= I_PB(6);
++ t2_pb6_t1 <= t2_pb6;
++ end if;
++ end if;
++ end process;
++
++ p_timer2_done : process(t2c,phase)
++ variable done : boolean;
++ begin
++ done := (t2c = x"0000");
++ t2c_done <= done and (phase = "11");
++ --if (phase = "11") then
++ t2_reload_counter <= done;
++ --end if;
++ end process;
++
++ p_timer2 : process
++ variable ena : boolean;
++ begin
++ wait until rising_edge(CLK);
++ if (ENA_4 = '1') then
++ if (r_acr(5) = '0') then
++ ena := true;
++ else
++ ena := (t2_pb6_t1 = '1') and (t2_pb6 = '0'); -- falling edge
++ end if;
++
++ if t2_load_counter or (t2_reload_counter and phase = "11") then
++ -- not sure if t2c_reload should be here. Does timer2 just continue to
++ -- count down, or is it reloaded ? Reloaded makes more sense if using
++ -- it to generate a clock for the shift register.
++ t2c( 7 downto 0) <= r_t2l_l;
++ t2c(15 downto 8) <= r_t2l_h;
++ else
++ if (phase="11") and ena then -- or count mode
++ t2c <= t2c - "1";
++ end if;
++ end if;
++
++ t2_sr_ena <= (t2c(7 downto 0) = x"00") and (phase = "11");
++
++ if t2_load_counter then
++ t2c_active <= true;
++ elsif t2c_done then
++ t2c_active <= false;
++ end if;
++ if RESET_L = '0' then
++ t2c_active <= false;
++ end if;
++
++ if t2c_active and t2c_done then
++ t2_irq <= '1';
++ elsif RESET_L = '0' or t2_w_reset_int or t2_r_reset_int or (clear_irq(5) = '1') then
++ t2_irq <= '0';
++ end if;
++ end if;
++ end process;
++ --
++ -- Shift Register
++ --
++ p_sr : process(RESET_L, CLK)
++ variable dir_out : std_logic;
++ variable ena : std_logic;
++ variable cb1_op : std_logic;
++ variable cb1_ip : std_logic;
++ variable use_t2 : std_logic;
++ variable free_run : std_logic;
++ variable sr_count_ena : boolean;
++ begin
++ if (RESET_L = '0') then
++ r_sr <= x"00";
++ sr_drive_cb2 <= '0';
++ sr_cb1_oe_l <= '1';
++ sr_cb1_out <= '0';
++ sr_strobe <= '1';
++ sr_cnt <= "0000";
++ sr_irq <= '0';
++ sr_out <= '1';
++ sr_off_delay <= '0';
++ elsif rising_edge(CLK) then
++ if (ENA_4 = '1') then
++ -- decode mode
++ dir_out := r_acr(4); -- output on cb2
++ cb1_op := '0';
++ cb1_ip := '0';
++ use_t2 := '0';
++ free_run := '0';
++
++ case r_acr(4 downto 2) is
++ when "000" => ena := '0'; cb1_ip := '1';
++ when "001" => ena := '1'; cb1_op := '1'; use_t2 := '1';
++ when "010" => ena := '1'; cb1_op := '1';
++ when "011" => ena := '1'; cb1_ip := '1';
++ when "100" => ena := '1'; use_t2 := '1'; free_run := '1';
++ when "101" => ena := '1'; cb1_op := '1'; use_t2 := '1';
++ when "110" => ena := '1';
++ when "111" => ena := '1'; cb1_ip := '1';
++ when others => null;
++ end case;
++
++ -- clock select
++ -- SR still runs even in disabled mode (on rising edge of CB1). It
++ -- just doesn't generate any interrupts.
++ -- Ref BBC micro advanced user guide p409
++ if (cb1_ip = '1') then
++ sr_strobe <= I_CB1;
++ else
++ if (sr_cnt(3) = '0') and (free_run = '0') then
++ sr_strobe <= '1';
++ else
++ if ((use_t2 = '1') and t2_sr_ena) or
++ ((use_t2 = '0') and (phase = "00")) then
++ sr_strobe <= not sr_strobe;
++ end if;
++ end if;
++ end if;
++
++ -- latch on rising edge, shift on falling edge
++ if sr_write_ena then
++ r_sr <= load_data;
++ else
++ if (dir_out = '0') then
++ -- input
++ if (sr_cnt(3) = '1') or (cb1_ip = '1') then
++ if sr_strobe_rising then
++ r_sr <= r_sr(6 downto 0) & I_CB2;
++ end if;
++ end if;
++ sr_out <= '1';
++ else
++ -- output
++ if (sr_cnt(3) = '1') or (sr_off_delay = '1') or (cb1_ip = '1') or (free_run = '1') then
++ if sr_strobe_falling then
++ r_sr(7 downto 1) <= r_sr(6 downto 0);
++ r_sr(0) <= r_sr(7);
++ sr_out <= r_sr(7);
++ end if;
++ else
++ sr_out <= '1';
++ end if;
++ end if;
++ end if;
++
++ sr_count_ena := sr_strobe_rising;
++
++ if sr_write_ena or sr_read_ena then
++ -- some documentation says sr bit in IFR must be set as well ?
++ sr_cnt <= "1000";
++ elsif sr_count_ena and (sr_cnt(3) = '1') then
++ sr_cnt <= sr_cnt + "1";
++ end if;
++
++ if (phase = "00") then
++ sr_off_delay <= sr_cnt(3); -- give some hold time when shifting out
++ end if;
++
++ if sr_count_ena and (sr_cnt = "1111") and (ena = '1') and (free_run = '0') then
++ sr_irq <= '1';
++ elsif sr_write_ena or sr_read_ena or (clear_irq(2) = '1') then
++ sr_irq <= '0';
++ end if;
++
++ -- assign ops
++ sr_drive_cb2 <= dir_out;
++ sr_cb1_oe_l <= not cb1_op;
++ sr_cb1_out <= sr_strobe;
++ end if;
++ end if;
++ end process;
++
++ p_sr_strobe_rise_fall : process
++ begin
++ wait until rising_edge(CLK);
++ if (ENA_4 = '1') then
++ sr_strobe_t1 <= sr_strobe;
++ sr_strobe_rising <= (sr_strobe_t1 = '0') and (sr_strobe = '1');
++ sr_strobe_falling <= (sr_strobe_t1 = '1') and (sr_strobe = '0');
++ end if;
++ end process;
++ --
++ -- Interrupts
++ --
++ p_ier : process(RESET_L, CLK)
++ begin
++ if (RESET_L = '0') then
++ r_ier <= "0000000";
++ elsif rising_edge(CLK) then
++ if (ENA_4 = '1') then
++ if ier_write_ena then
++ if (load_data(7) = '1') then
++ -- set
++ r_ier <= r_ier or load_data(6 downto 0);
++ else
++ -- clear
++ r_ier <= r_ier and not load_data(6 downto 0);
++ end if;
++ end if;
++ end if;
++ end if;
++ end process;
++
++ p_ifr : process(t1_irq, t2_irq, final_irq, ca1_irq, ca2_irq, sr_irq,
++ cb1_irq, cb2_irq)
++ begin
++ r_ifr(7) <= final_irq;
++ r_ifr(6) <= t1_irq;
++ r_ifr(5) <= t2_irq;
++ r_ifr(4) <= cb1_irq;
++ r_ifr(3) <= cb2_irq;
++ r_ifr(2) <= sr_irq;
++ r_ifr(1) <= ca1_irq;
++ r_ifr(0) <= ca2_irq;
++
++ O_IRQ_L <= not final_irq;
++ end process;
++
++ p_irq : process(RESET_L, CLK)
++ begin
++ if (RESET_L = '0') then
++ final_irq <= '0';
++ elsif rising_edge(CLK) then
++ if (ENA_4 = '1') then
++ if ((r_ifr(6 downto 0) and r_ier(6 downto 0)) = "0000000") then
++ final_irq <= '0'; -- no interrupts
++ else
++ final_irq <= '1';
++ end if;
++ end if;
++ end if;
++ end process;
++
++ p_clear_irq : process(ifr_write_ena, load_data)
++ begin
++ clear_irq <= x"00";
++ if ifr_write_ena then
++ clear_irq <= load_data;
++ end if;
++ end process;
++
++end architecture RTL;
+diff --git a/m6522_tb.vhd b/m6522_tb.vhd
+index 3e4262d..30307d2 100644
+--- a/m6522_tb.vhd
++++ b/m6522_tb.vhd
+@@ -1,378 +1,378 @@
+--- BBC Micro for Altera DE1
+---
+--- Copyright (c) 2011 Mike Stirling
+---
+--- 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 agreement from the author.
+---
+--- * License is granted for non-commercial use only. A fee may not be charged
+--- for redistributions as source code or in synthesized/hardware form without
+--- specific prior written agreement from the author.
+---
+--- 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.
+---
+-
+-library IEEE;
+-use IEEE.STD_LOGIC_1164.ALL;
+-use IEEE.NUMERIC_STD.ALL;
+-
+-entity m6522_tb is
+-end entity;
+-
+-architecture tb of m6522_tb is
+-
+-component M6522 is
+- port (
+-
+- I_RS : in std_logic_vector(3 downto 0);
+- I_DATA : in std_logic_vector(7 downto 0);
+- O_DATA : out std_logic_vector(7 downto 0);
+- O_DATA_OE_L : out std_logic;
+-
+- I_RW_L : in std_logic;
+- I_CS1 : in std_logic;
+- I_CS2_L : in std_logic;
+-
+- O_IRQ_L : out std_logic; -- note, not open drain
+- -- port a
+- I_CA1 : in std_logic;
+- I_CA2 : in std_logic;
+- O_CA2 : out std_logic;
+- O_CA2_OE_L : out std_logic;
+-
+- I_PA : in std_logic_vector(7 downto 0);
+- O_PA : out std_logic_vector(7 downto 0);
+- O_PA_OE_L : out std_logic_vector(7 downto 0);
+-
+- -- port b
+- I_CB1 : in std_logic;
+- O_CB1 : out std_logic;
+- O_CB1_OE_L : out std_logic;
+-
+- I_CB2 : in std_logic;
+- O_CB2 : out std_logic;
+- O_CB2_OE_L : out std_logic;
+-
+- I_PB : in std_logic_vector(7 downto 0);
+- O_PB : out std_logic_vector(7 downto 0);
+- O_PB_OE_L : out std_logic_vector(7 downto 0);
+-
+- I_P2_H : in std_logic; -- high for phase 2 clock ____----__
+- RESET_L : in std_logic;
+- ENA_4 : in std_logic; -- clk enable
+- CLK : in std_logic
+- );
+-end component;
+-
+-signal rs : std_logic_vector(3 downto 0) := "0000";
+-signal di : std_logic_vector(7 downto 0) := "00000000";
+-signal do : std_logic_vector(7 downto 0);
+-signal n_d_oe : std_logic;
+-signal r_nw : std_logic := '1';
+-signal cs1 : std_logic := '0';
+-signal n_cs2 : std_logic := '0';
+-signal n_irq : std_logic;
+-signal ca1_in : std_logic := '0';
+-signal ca2_in : std_logic := '0';
+-signal ca2_out : std_logic;
+-signal n_ca2_oe : std_logic;
+-signal pa_in : std_logic_vector(7 downto 0) := "00000000";
+-signal pa_out : std_logic_vector(7 downto 0);
+-signal n_pa_oe : std_logic_vector(7 downto 0);
+-signal cb1_in : std_logic := '0';
+-signal cb1_out : std_logic;
+-signal n_cb1_oe : std_logic;
+-signal cb2_in : std_logic := '0';
+-signal cb2_out : std_logic;
+-signal n_cb2_oe : std_logic;
+-signal pb_in : std_logic_vector(7 downto 0) := "00000000";
+-signal pb_out : std_logic_vector(7 downto 0);
+-signal n_pb_oe : std_logic_vector(7 downto 0);
+-
+-signal phase2 : std_logic := '0';
+-signal n_reset : std_logic := '0';
+-signal clken : std_logic := '0';
+-signal clock : std_logic := '0';
+-
+-begin
+-
+- uut: m6522 port map (
+- rs, di, do, n_d_oe,
+- r_nw, cs1, n_cs2, n_irq,
+- ca1_in, ca2_in, ca2_out, n_ca2_oe,
+- pa_in, pa_out, n_pa_oe,
+- cb1_in, cb1_out, n_cb1_oe,
+- cb2_in, cb2_out, n_cb2_oe,
+- pb_in, pb_out, n_pb_oe,
+- phase2, n_reset, clken, clock
+- );
+-
+- clock <= not clock after 125 ns; -- 4x 1 MHz
+- phase2 <= not phase2 after 500 ns;
+- clken <= '1'; -- all cycles enabled
+-
+- process
+- begin
+- wait for 1 us;
+- -- Release reset
+- n_reset <= '1';
+- end process;
+-
+- process
+-
+- procedure reg_write(
+- a : in std_logic_vector(3 downto 0);
+- d : in std_logic_vector(7 downto 0)) is
+- begin
+- wait until falling_edge(phase2);
+- rs <= a;
+- di <= d;
+- cs1 <= '1';
+- r_nw <= '0';
+- wait until falling_edge(phase2);
+- cs1 <= '0';
+- r_nw <= '1';
+- end procedure;
+-
+- procedure reg_read(
+- a : in std_logic_vector(3 downto 0)) is
+- begin
+- wait until falling_edge(phase2);
+- rs <= a;
+- cs1 <= '1';
+- r_nw <= '1';
+- wait until falling_edge(phase2);
+- cs1 <= '0';
+- end procedure;
+-
+- begin
+- wait for 2 us;
+-
+- -- Set port A and B to output
+- reg_write("0010","11111111");
+- reg_write("0011","11111111");
+-
+- -- Write to port B
+- reg_write("0000","10101010");
+- -- Write to port B
+- reg_write("0000","01010101");
+- -- Write to port A (no handshake)
+- reg_write("1111","10101010");
+- -- Write to port A (with handshake)
+- reg_write("0001","01010101");
+-
+- -- Set port A and B to input
+- reg_write("0010","00000000");
+- reg_write("0011","00000000");
+-
+- -- Apply input stimuli and read from ports
+- pa_in <= "10101010";
+- pb_in <= "01010101";
+- reg_read("0000");
+- reg_read("0001");
+-
+- -- Test CA1 interrupt
+- ca1_in <= '0';
+- reg_write("1100","00000001"); -- PCR - interrupt on rising edge
+- reg_write("1101","01111111"); -- Clear interrupts
+- reg_write("1110","01111111"); -- Disable all interrupts
+- reg_write("1110","10000010"); -- Enable CA1 interrupt
+- ca1_in <= '1'; -- Trigger event
+- wait for 2 us;
+- reg_read("1101");
+- reg_read("0001"); -- Should clear interrupt
+- wait for 2 us;
+- reg_write("1100","00000000"); -- PCR - interrupt on falling edge
+- ca1_in <= '0'; -- Trigger event
+- wait for 2 us;
+- reg_read("1101");
+- reg_write("1101","00000010"); -- Should clear interrupt
+- wait for 2 us;
+- reg_write("1110","00000010"); -- Disable CA1 interrupt
+-
+- -- Test CB1 interrupt
+- cb1_in <= '0';
+- reg_write("1100","00010000"); -- PCR - interrupt on rising edge
+- reg_write("1101","01111111"); -- Clear interrupts
+- reg_write("1110","01111111"); -- Disable all interrupts
+- reg_write("1110","10010000"); -- Enable CB1 interrupt
+- cb1_in <= '1'; -- Trigger event
+- wait for 2 us;
+- reg_read("1101");
+- reg_read("0000"); -- Should clear interrupt
+- wait for 2 us;
+- reg_write("1100","00000000"); -- PCR - interrupt on falling edge
+- cb1_in <= '0'; -- Trigger event
+- wait for 2 us;
+- reg_read("1101");
+- reg_write("1101","00010000"); -- Should clear interrupt
+- wait for 2 us;
+- reg_write("1110","00010000"); -- Disable CA1 interrupt
+-
+- -- Test CA2 interrupt modes
+- reg_write("1101","01111111"); -- Clear interrupts
+- reg_write("1110","01111111"); -- Disable all interrupts
+- reg_write("1110","10000001"); -- Enable CA2 interrupt
+- -- mode 2 (+ve edge, clear on read/write)
+- reg_write("1100","00000100"); -- PCR
+- ca2_in <= '1'; -- Trigger event
+- wait for 2 us;
+- reg_read("1101");
+- reg_read("1111"); -- Should not clear interrupt
+- reg_read("0001"); -- Should clear interrupt
+- wait for 2 us;
+- -- mode 0 (-ve edge, clear on read/write)
+- reg_write("1100","00000000"); -- PCR
+- ca2_in <= '0'; -- Trigger event
+- wait for 2 us;
+- reg_read("1101");
+- reg_read("1111"); -- Should not clear interrupt
+- reg_read("0001"); -- Should clear interrupt
+- wait for 2 us;
+- -- mode 3 (+ve edge, don't clear on read/write)
+- reg_write("1100","00000110");
+- ca2_in <= '1'; -- Trigger event
+- wait for 2 us;
+- reg_read("1101");
+- reg_read("1111"); -- Should not clear interrupt
+- reg_read("0001"); -- Should not clear interrupt
+- reg_write("1101","00000001"); -- Should clear interrupt
+- wait for 2 us;
+- -- mode 1 (-ve edge, don't clear on read/write)
+- reg_write("1100","00000010");
+- ca2_in <= '0'; -- Trigger event
+- wait for 2 us;
+- reg_read("1101");
+- reg_read("1111"); -- Should not clear interrupt
+- reg_read("0001"); -- Should not clear interrupt
+- reg_write("1101","00000001"); -- Should clear interrupt
+- wait for 2 us;
+-
+- -- Test CA2 output modes
+- -- mode 4 (set low on read/write of ORA, set high on CA1 interrupt edge)
+- reg_write("1100","00001000");
+- -- mode 5 (set low for 1 cycle on read/write ORA)
+- reg_write("1100","00001010");
+- -- mode 6 (held low)
+- reg_write("1100","00001100");
+- -- mode 7 (held high)
+- reg_write("1100","00001110");
+-
+- -- Test CB2 interrupt modes
+- reg_write("1101","01111111"); -- Clear interrupts
+- reg_write("1110","01111111"); -- Disable all interrupts
+- reg_write("1110","10001000"); -- Enable CB2 interrupt
+- -- mode 2 (+ve edge, clear on read/write)
+- reg_write("1100","01000000"); -- PCR
+- cb2_in <= '1'; -- Trigger event
+- wait for 2 us;
+- reg_read("1101");
+- reg_read("0000"); -- Should clear interrupt
+- wait for 2 us;
+- -- mode 0 (-ve edge, clear on read/write)
+- reg_write("1100","00000000"); -- PCR
+- cb2_in <= '0'; -- Trigger event
+- wait for 2 us;
+- reg_read("1101");
+- reg_read("0000"); -- Should clear interrupt
+- wait for 2 us;
+- -- mode 3 (+ve edge, don't clear on read/write)
+- reg_write("1100","01100000");
+- cb2_in <= '1'; -- Trigger event
+- wait for 2 us;
+- reg_read("1101");
+- reg_read("0000"); -- Should not clear interrupt
+- reg_write("1101","00001000"); -- Should clear interrupt
+- wait for 2 us;
+- -- mode 1 (-ve edge, don't clear on read/write)
+- reg_write("1100","00100000");
+- cb2_in <= '0'; -- Trigger event
+- wait for 2 us;
+- reg_read("1101");
+- reg_read("0000"); -- Should not clear interrupt
+- reg_write("1101","00001000"); -- Should clear interrupt
+- wait for 2 us;
+-
+- -- Test CB2 output modes
+- -- mode 4 (set low on read/write of ORA, set high on CA1 interrupt edge)
+- reg_write("1100","10000000");
+- -- mode 5 (set low for 1 cycle on read/write ORA)
+- reg_write("1100","10100000");
+- -- mode 6 (held low)
+- reg_write("1100","11000000");
+- -- mode 7 (held high)
+- reg_write("1100","11100000");
+-
+- -- Timer 1 timeout
+- reg_write("1101","01111111"); -- Clear interrupts
+- reg_write("1110","01111111"); -- Disable all interrupts
+- reg_write("1110","11000000"); -- Enable timer 1 interrupt
+- -- Count to 16
+- reg_write("0100","00010000");
+- reg_write("0101","00000000");
+- wait for 50 us;
+- -- Count to 16
+- reg_write("0100","00010000");
+- reg_write("0101","00000000"); -- Should clear interrupt
+- wait for 50 us;
+- reg_read("0100"); -- Should clear interrupt
+-
+- -- Timer 2 timeout
+- reg_write("1101","01111111"); -- Clear interrupts
+- reg_write("1110","01111111"); -- Disable all interrupts
+- reg_write("1110","10100000"); -- Enable timer 2 interrupt
+- -- Count to 16
+- reg_write("1000","00010000");
+- reg_write("1001","00000000");
+- wait for 50 us;
+- -- Count to 16
+- reg_write("1000","00010000");
+- reg_write("1001","00000000"); -- Should clear interrupt
+- wait for 50 us;
+- reg_read("1000"); -- Should clear interrupt
+-
+- -- Timer 2 test similar to BBC usage (speech interrupt)
+- -- PB6 high
+- pb_in(6) <= '1';
+- reg_write("1101","01111111"); -- Clear interrupts
+- reg_write("1110","01111111"); -- Disable all interrupts
+- reg_write("1011","00100000"); -- Timer 2 PB6 counter mode
+- reg_write("1000","00000001"); -- Start at 1
+- reg_write("1001","00000000");
+- reg_write("1110","10100000"); -- Enable timer 2 interrupt
+- wait for 5 us;
+- -- Generate falling edge
+- pb_in(6) <= '0';
+- wait for 5 us;
+- -- Clear interrupt
+- reg_write("1101","00100000");
+- -- Zero timer high byte
+- reg_write("1001","00000000");
+-
+- wait;
+- end process;
+-
+-end architecture;
++-- BBC Micro for Altera DE1
++--
++-- Copyright (c) 2011 Mike Stirling
++--
++-- 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 agreement from the author.
++--
++-- * License is granted for non-commercial use only. A fee may not be charged
++-- for redistributions as source code or in synthesized/hardware form without
++-- specific prior written agreement from the author.
++--
++-- 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.
++--
++
++library IEEE;
++use IEEE.STD_LOGIC_1164.ALL;
++use IEEE.NUMERIC_STD.ALL;
++
++entity m6522_tb is
++end entity;
++
++architecture tb of m6522_tb is
++
++component M6522 is
++ port (
++
++ I_RS : in std_logic_vector(3 downto 0);
++ I_DATA : in std_logic_vector(7 downto 0);
++ O_DATA : out std_logic_vector(7 downto 0);
++ O_DATA_OE_L : out std_logic;
++
++ I_RW_L : in std_logic;
++ I_CS1 : in std_logic;
++ I_CS2_L : in std_logic;
++
++ O_IRQ_L : out std_logic; -- note, not open drain
++ -- port a
++ I_CA1 : in std_logic;
++ I_CA2 : in std_logic;
++ O_CA2 : out std_logic;
++ O_CA2_OE_L : out std_logic;
++
++ I_PA : in std_logic_vector(7 downto 0);
++ O_PA : out std_logic_vector(7 downto 0);
++ O_PA_OE_L : out std_logic_vector(7 downto 0);
++
++ -- port b
++ I_CB1 : in std_logic;
++ O_CB1 : out std_logic;
++ O_CB1_OE_L : out std_logic;
++
++ I_CB2 : in std_logic;
++ O_CB2 : out std_logic;
++ O_CB2_OE_L : out std_logic;
++
++ I_PB : in std_logic_vector(7 downto 0);
++ O_PB : out std_logic_vector(7 downto 0);
++ O_PB_OE_L : out std_logic_vector(7 downto 0);
++
++ I_P2_H : in std_logic; -- high for phase 2 clock ____----__
++ RESET_L : in std_logic;
++ ENA_4 : in std_logic; -- clk enable
++ CLK : in std_logic
++ );
++end component;
++
++signal rs : std_logic_vector(3 downto 0) := "0000";
++signal di : std_logic_vector(7 downto 0) := "00000000";
++signal do : std_logic_vector(7 downto 0);
++signal n_d_oe : std_logic;
++signal r_nw : std_logic := '1';
++signal cs1 : std_logic := '0';
++signal n_cs2 : std_logic := '0';
++signal n_irq : std_logic;
++signal ca1_in : std_logic := '0';
++signal ca2_in : std_logic := '0';
++signal ca2_out : std_logic;
++signal n_ca2_oe : std_logic;
++signal pa_in : std_logic_vector(7 downto 0) := "00000000";
++signal pa_out : std_logic_vector(7 downto 0);
++signal n_pa_oe : std_logic_vector(7 downto 0);
++signal cb1_in : std_logic := '0';
++signal cb1_out : std_logic;
++signal n_cb1_oe : std_logic;
++signal cb2_in : std_logic := '0';
++signal cb2_out : std_logic;
++signal n_cb2_oe : std_logic;
++signal pb_in : std_logic_vector(7 downto 0) := "00000000";
++signal pb_out : std_logic_vector(7 downto 0);
++signal n_pb_oe : std_logic_vector(7 downto 0);
++
++signal phase2 : std_logic := '0';
++signal n_reset : std_logic := '0';
++signal clken : std_logic := '0';
++signal clock : std_logic := '0';
++
++begin
++
++ uut: m6522 port map (
++ rs, di, do, n_d_oe,
++ r_nw, cs1, n_cs2, n_irq,
++ ca1_in, ca2_in, ca2_out, n_ca2_oe,
++ pa_in, pa_out, n_pa_oe,
++ cb1_in, cb1_out, n_cb1_oe,
++ cb2_in, cb2_out, n_cb2_oe,
++ pb_in, pb_out, n_pb_oe,
++ phase2, n_reset, clken, clock
++ );
++
++ clock <= not clock after 125 ns; -- 4x 1 MHz
++ phase2 <= not phase2 after 500 ns;
++ clken <= '1'; -- all cycles enabled
++
++ process
++ begin
++ wait for 1 us;
++ -- Release reset
++ n_reset <= '1';
++ end process;
++
++ process
++
++ procedure reg_write(
++ a : in std_logic_vector(3 downto 0);
++ d : in std_logic_vector(7 downto 0)) is
++ begin
++ wait until falling_edge(phase2);
++ rs <= a;
++ di <= d;
++ cs1 <= '1';
++ r_nw <= '0';
++ wait until falling_edge(phase2);
++ cs1 <= '0';
++ r_nw <= '1';
++ end procedure;
++
++ procedure reg_read(
++ a : in std_logic_vector(3 downto 0)) is
++ begin
++ wait until falling_edge(phase2);
++ rs <= a;
++ cs1 <= '1';
++ r_nw <= '1';
++ wait until falling_edge(phase2);
++ cs1 <= '0';
++ end procedure;
++
++ begin
++ wait for 2 us;
++
++ -- Set port A and B to output
++ reg_write("0010","11111111");
++ reg_write("0011","11111111");
++
++ -- Write to port B
++ reg_write("0000","10101010");
++ -- Write to port B
++ reg_write("0000","01010101");
++ -- Write to port A (no handshake)
++ reg_write("1111","10101010");
++ -- Write to port A (with handshake)
++ reg_write("0001","01010101");
++
++ -- Set port A and B to input
++ reg_write("0010","00000000");
++ reg_write("0011","00000000");
++
++ -- Apply input stimuli and read from ports
++ pa_in <= "10101010";
++ pb_in <= "01010101";
++ reg_read("0000");
++ reg_read("0001");
++
++ -- Test CA1 interrupt
++ ca1_in <= '0';
++ reg_write("1100","00000001"); -- PCR - interrupt on rising edge
++ reg_write("1101","01111111"); -- Clear interrupts
++ reg_write("1110","01111111"); -- Disable all interrupts
++ reg_write("1110","10000010"); -- Enable CA1 interrupt
++ ca1_in <= '1'; -- Trigger event
++ wait for 2 us;
++ reg_read("1101");
++ reg_read("0001"); -- Should clear interrupt
++ wait for 2 us;
++ reg_write("1100","00000000"); -- PCR - interrupt on falling edge
++ ca1_in <= '0'; -- Trigger event
++ wait for 2 us;
++ reg_read("1101");
++ reg_write("1101","00000010"); -- Should clear interrupt
++ wait for 2 us;
++ reg_write("1110","00000010"); -- Disable CA1 interrupt
++
++ -- Test CB1 interrupt
++ cb1_in <= '0';
++ reg_write("1100","00010000"); -- PCR - interrupt on rising edge
++ reg_write("1101","01111111"); -- Clear interrupts
++ reg_write("1110","01111111"); -- Disable all interrupts
++ reg_write("1110","10010000"); -- Enable CB1 interrupt
++ cb1_in <= '1'; -- Trigger event
++ wait for 2 us;
++ reg_read("1101");
++ reg_read("0000"); -- Should clear interrupt
++ wait for 2 us;
++ reg_write("1100","00000000"); -- PCR - interrupt on falling edge
++ cb1_in <= '0'; -- Trigger event
++ wait for 2 us;
++ reg_read("1101");
++ reg_write("1101","00010000"); -- Should clear interrupt
++ wait for 2 us;
++ reg_write("1110","00010000"); -- Disable CA1 interrupt
++
++ -- Test CA2 interrupt modes
++ reg_write("1101","01111111"); -- Clear interrupts
++ reg_write("1110","01111111"); -- Disable all interrupts
++ reg_write("1110","10000001"); -- Enable CA2 interrupt
++ -- mode 2 (+ve edge, clear on read/write)
++ reg_write("1100","00000100"); -- PCR
++ ca2_in <= '1'; -- Trigger event
++ wait for 2 us;
++ reg_read("1101");
++ reg_read("1111"); -- Should not clear interrupt
++ reg_read("0001"); -- Should clear interrupt
++ wait for 2 us;
++ -- mode 0 (-ve edge, clear on read/write)
++ reg_write("1100","00000000"); -- PCR
++ ca2_in <= '0'; -- Trigger event
++ wait for 2 us;
++ reg_read("1101");
++ reg_read("1111"); -- Should not clear interrupt
++ reg_read("0001"); -- Should clear interrupt
++ wait for 2 us;
++ -- mode 3 (+ve edge, don't clear on read/write)
++ reg_write("1100","00000110");
++ ca2_in <= '1'; -- Trigger event
++ wait for 2 us;
++ reg_read("1101");
++ reg_read("1111"); -- Should not clear interrupt
++ reg_read("0001"); -- Should not clear interrupt
++ reg_write("1101","00000001"); -- Should clear interrupt
++ wait for 2 us;
++ -- mode 1 (-ve edge, don't clear on read/write)
++ reg_write("1100","00000010");
++ ca2_in <= '0'; -- Trigger event
++ wait for 2 us;
++ reg_read("1101");
++ reg_read("1111"); -- Should not clear interrupt
++ reg_read("0001"); -- Should not clear interrupt
++ reg_write("1101","00000001"); -- Should clear interrupt
++ wait for 2 us;
++
++ -- Test CA2 output modes
++ -- mode 4 (set low on read/write of ORA, set high on CA1 interrupt edge)
++ reg_write("1100","00001000");
++ -- mode 5 (set low for 1 cycle on read/write ORA)
++ reg_write("1100","00001010");
++ -- mode 6 (held low)
++ reg_write("1100","00001100");
++ -- mode 7 (held high)
++ reg_write("1100","00001110");
++
++ -- Test CB2 interrupt modes
++ reg_write("1101","01111111"); -- Clear interrupts
++ reg_write("1110","01111111"); -- Disable all interrupts
++ reg_write("1110","10001000"); -- Enable CB2 interrupt
++ -- mode 2 (+ve edge, clear on read/write)
++ reg_write("1100","01000000"); -- PCR
++ cb2_in <= '1'; -- Trigger event
++ wait for 2 us;
++ reg_read("1101");
++ reg_read("0000"); -- Should clear interrupt
++ wait for 2 us;
++ -- mode 0 (-ve edge, clear on read/write)
++ reg_write("1100","00000000"); -- PCR
++ cb2_in <= '0'; -- Trigger event
++ wait for 2 us;
++ reg_read("1101");
++ reg_read("0000"); -- Should clear interrupt
++ wait for 2 us;
++ -- mode 3 (+ve edge, don't clear on read/write)
++ reg_write("1100","01100000");
++ cb2_in <= '1'; -- Trigger event
++ wait for 2 us;
++ reg_read("1101");
++ reg_read("0000"); -- Should not clear interrupt
++ reg_write("1101","00001000"); -- Should clear interrupt
++ wait for 2 us;
++ -- mode 1 (-ve edge, don't clear on read/write)
++ reg_write("1100","00100000");
++ cb2_in <= '0'; -- Trigger event
++ wait for 2 us;
++ reg_read("1101");
++ reg_read("0000"); -- Should not clear interrupt
++ reg_write("1101","00001000"); -- Should clear interrupt
++ wait for 2 us;
++
++ -- Test CB2 output modes
++ -- mode 4 (set low on read/write of ORA, set high on CA1 interrupt edge)
++ reg_write("1100","10000000");
++ -- mode 5 (set low for 1 cycle on read/write ORA)
++ reg_write("1100","10100000");
++ -- mode 6 (held low)
++ reg_write("1100","11000000");
++ -- mode 7 (held high)
++ reg_write("1100","11100000");
++
++ -- Timer 1 timeout
++ reg_write("1101","01111111"); -- Clear interrupts
++ reg_write("1110","01111111"); -- Disable all interrupts
++ reg_write("1110","11000000"); -- Enable timer 1 interrupt
++ -- Count to 16
++ reg_write("0100","00010000");
++ reg_write("0101","00000000");
++ wait for 50 us;
++ -- Count to 16
++ reg_write("0100","00010000");
++ reg_write("0101","00000000"); -- Should clear interrupt
++ wait for 50 us;
++ reg_read("0100"); -- Should clear interrupt
++
++ -- Timer 2 timeout
++ reg_write("1101","01111111"); -- Clear interrupts
++ reg_write("1110","01111111"); -- Disable all interrupts
++ reg_write("1110","10100000"); -- Enable timer 2 interrupt
++ -- Count to 16
++ reg_write("1000","00010000");
++ reg_write("1001","00000000");
++ wait for 50 us;
++ -- Count to 16
++ reg_write("1000","00010000");
++ reg_write("1001","00000000"); -- Should clear interrupt
++ wait for 50 us;
++ reg_read("1000"); -- Should clear interrupt
++
++ -- Timer 2 test similar to BBC usage (speech interrupt)
++ -- PB6 high
++ pb_in(6) <= '1';
++ reg_write("1101","01111111"); -- Clear interrupts
++ reg_write("1110","01111111"); -- Disable all interrupts
++ reg_write("1011","00100000"); -- Timer 2 PB6 counter mode
++ reg_write("1000","00000001"); -- Start at 1
++ reg_write("1001","00000000");
++ reg_write("1110","10100000"); -- Enable timer 2 interrupt
++ wait for 5 us;
++ -- Generate falling edge
++ pb_in(6) <= '0';
++ wait for 5 us;
++ -- Clear interrupt
++ reg_write("1101","00100000");
++ -- Zero timer high byte
++ reg_write("1001","00000000");
++
++ wait;
++ end process;
++
++end architecture;
+diff --git a/mc6845.vhd b/mc6845.vhd
+index 31208ea..c102501 100644
+--- a/mc6845.vhd
++++ b/mc6845.vhd
+@@ -1,481 +1,481 @@
+--- BBC Micro for Altera DE1
+---
+--- Copyright (c) 2011 Mike Stirling
+---
+--- 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 agreement from the author.
+---
+--- * License is granted for non-commercial use only. A fee may not be charged
+--- for redistributions as source code or in synthesized/hardware form without
+--- specific prior written agreement from the author.
+---
+--- 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.
+---
+--- 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
++-- BBC Micro for Altera DE1
++--
++-- Copyright (c) 2011 Mike Stirling
++--
++-- 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 agreement from the author.
++--
++-- * License is granted for non-commercial use only. A fee may not be charged
++-- for redistributions as source code or in synthesized/hardware form without
++-- specific prior written agreement from the author.
++--
++-- 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.
++--
++-- 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);
+- variable max_scan_line : unsigned(4 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');
+-
+- -- In interlace sync + video mode mask off the LSb of the
+- -- max scan line address
+- if r08_interlace = "11" then
+- max_scan_line := r09_max_scan_line_addr(4 downto 1) & "0";
+- else
+- max_scan_line := r09_max_scan_line_addr;
+- end if;
+-
+- -- Scan line counter increments, wrapping at max_scan_line_addr
+- if line_counter = max_scan_line 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 character 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. Count in twos in interlaced sync+video mode
+- if r08_interlace = "11" then
+- line_counter <= line_counter + 2;
+- line_counter(0) <= '0'; -- Force to even
+- else
+- line_counter <= line_counter + 1;
+- end if;
+- 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)
+- variable slv_line : std_logic_vector(4 downto 0);
+- begin
+- if nRESET = '0' then
+- RA <= (others => '0');
+- MA <= (others => '0');
+- elsif rising_edge(CLOCK) and CLKEN = '1' then
+- slv_line := std_logic_vector(line_counter);
+-
+- -- Character row address is just the scan line counter delayed by
+- -- one clock to line up with the syncs.
+- if r08_interlace = "11" then
+- -- In interlace sync and video mode the LSb is determined by the
+- -- field number. The line counter counts up in 2s in this case.
+- RA <= slv_line(4 downto 1) & (slv_line(0) or odd_field);
+- else
+- RA <= slv_line;
+- end if;
+- -- 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 h_display = '1' and v_display = '1' and ma_i = r14_cursor_h & r15_cursor_l then
+- if line_counter = 0 then
+- -- Suppress wrap around if last line is > max scan line
+- cursor_line := '0';
+- end if;
+- 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;
+-
+-
++ 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);
++ variable max_scan_line : unsigned(4 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');
++
++ -- In interlace sync + video mode mask off the LSb of the
++ -- max scan line address
++ if r08_interlace = "11" then
++ max_scan_line := r09_max_scan_line_addr(4 downto 1) & "0";
++ else
++ max_scan_line := r09_max_scan_line_addr;
++ end if;
++
++ -- Scan line counter increments, wrapping at max_scan_line_addr
++ if line_counter = max_scan_line 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 character 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. Count in twos in interlaced sync+video mode
++ if r08_interlace = "11" then
++ line_counter <= line_counter + 2;
++ line_counter(0) <= '0'; -- Force to even
++ else
++ line_counter <= line_counter + 1;
++ end if;
++ 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)
++ variable slv_line : std_logic_vector(4 downto 0);
++ begin
++ if nRESET = '0' then
++ RA <= (others => '0');
++ MA <= (others => '0');
++ elsif rising_edge(CLOCK) and CLKEN = '1' then
++ slv_line := std_logic_vector(line_counter);
++
++ -- Character row address is just the scan line counter delayed by
++ -- one clock to line up with the syncs.
++ if r08_interlace = "11" then
++ -- In interlace sync and video mode the LSb is determined by the
++ -- field number. The line counter counts up in 2s in this case.
++ RA <= slv_line(4 downto 1) & (slv_line(0) or odd_field);
++ else
++ RA <= slv_line;
++ end if;
++ -- 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 h_display = '1' and v_display = '1' and ma_i = r14_cursor_h & r15_cursor_l then
++ if line_counter = 0 then
++ -- Suppress wrap around if last line is > max scan line
++ cursor_line := '0';
++ end if;
++ 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/pll32.ppf b/pll32.ppf
+index 1ba6b2c..71486cf 100644
+--- a/pll32.ppf
++++ b/pll32.ppf
+@@ -1,11 +1,11 @@
+-<?xml version="1.0" encoding="UTF-8" ?>
+-<!DOCTYPE pinplan>
+-<pinplan intended_family="Cyclone II" variation_name="pll32" megafunction_name="ALTPLL" specifies="all_ports">
+-<global>
+-<pin name="areset" direction="input" scope="external" />
+-<pin name="inclk0" direction="input" scope="external" source="clock" />
+-<pin name="c0" direction="output" scope="external" source="clock" />
+-<pin name="locked" direction="output" scope="external" />
+-
+-</global>
+-</pinplan>
++<?xml version="1.0" encoding="UTF-8" ?>
++<!DOCTYPE pinplan>
++<pinplan intended_family="Cyclone II" variation_name="pll32" megafunction_name="ALTPLL" specifies="all_ports">
++<global>
++<pin name="areset" direction="input" scope="external" />
++<pin name="inclk0" direction="input" scope="external" source="clock" />
++<pin name="c0" direction="output" scope="external" source="clock" />
++<pin name="locked" direction="output" scope="external" />
++
++</global>
++</pinplan>
+diff --git a/pll32.qip b/pll32.qip
+index f78bd93..e82abed 100644
+--- a/pll32.qip
++++ b/pll32.qip
+@@ -1,4 +1,4 @@
+-set_global_assignment -name IP_TOOL_NAME "ALTPLL"
+-set_global_assignment -name IP_TOOL_VERSION "9.1"
+-set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "pll32.vhd"]
+-set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll32.ppf"]
++set_global_assignment -name IP_TOOL_NAME "ALTPLL"
++set_global_assignment -name IP_TOOL_VERSION "9.1"
++set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "pll32.vhd"]
++set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll32.ppf"]
+diff --git a/pll32.vhd b/pll32.vhd
+index 43df1aa..ab53700 100644
+--- a/pll32.vhd
++++ b/pll32.vhd
+@@ -1,365 +1,365 @@
+--- megafunction wizard: %ALTPLL%
+--- GENERATION: STANDARD
+--- VERSION: WM1.0
+--- MODULE: altpll
+-
+--- ============================================================
+--- File Name: pll32.vhd
+--- Megafunction Name(s):
+--- altpll
+---
+--- Simulation Library Files(s):
+--- altera_mf
+--- ============================================================
+--- ************************************************************
+--- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+---
+--- 9.1 Build 222 10/21/2009 SJ Web Edition
+--- ************************************************************
+-
+-
+---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.
+-
+-
+-LIBRARY ieee;
+-USE ieee.std_logic_1164.all;
+-
+-LIBRARY altera_mf;
+-USE altera_mf.all;
+-
+-ENTITY pll32 IS
+- PORT
+- (
+- areset : IN STD_LOGIC := '0';
+- inclk0 : IN STD_LOGIC := '0';
+- c0 : OUT STD_LOGIC ;
+- locked : OUT STD_LOGIC
+- );
+-END pll32;
+-
+-
+-ARCHITECTURE SYN OF pll32 IS
+-
+- SIGNAL sub_wire0 : STD_LOGIC_VECTOR (5 DOWNTO 0);
+- SIGNAL sub_wire1 : STD_LOGIC ;
+- SIGNAL sub_wire2 : STD_LOGIC ;
+- SIGNAL sub_wire3 : STD_LOGIC ;
+- SIGNAL sub_wire4 : STD_LOGIC_VECTOR (1 DOWNTO 0);
+- SIGNAL sub_wire5_bv : BIT_VECTOR (0 DOWNTO 0);
+- SIGNAL sub_wire5 : STD_LOGIC_VECTOR (0 DOWNTO 0);
+-
+-
+-
+- COMPONENT altpll
+- GENERIC (
+- clk0_divide_by : NATURAL;
+- clk0_duty_cycle : NATURAL;
+- clk0_multiply_by : NATURAL;
+- clk0_phase_shift : STRING;
+- compensate_clock : STRING;
+- gate_lock_signal : STRING;
+- inclk0_input_frequency : NATURAL;
+- intended_device_family : STRING;
+- invalid_lock_multiplier : NATURAL;
+- lpm_hint : STRING;
+- lpm_type : STRING;
+- operation_mode : STRING;
+- port_activeclock : STRING;
+- port_areset : STRING;
+- port_clkbad0 : STRING;
+- port_clkbad1 : STRING;
+- port_clkloss : STRING;
+- port_clkswitch : STRING;
+- port_configupdate : STRING;
+- port_fbin : STRING;
+- port_inclk0 : STRING;
+- port_inclk1 : STRING;
+- port_locked : STRING;
+- port_pfdena : STRING;
+- port_phasecounterselect : STRING;
+- port_phasedone : STRING;
+- port_phasestep : STRING;
+- port_phaseupdown : STRING;
+- port_pllena : STRING;
+- port_scanaclr : STRING;
+- port_scanclk : STRING;
+- port_scanclkena : STRING;
+- port_scandata : STRING;
+- port_scandataout : STRING;
+- port_scandone : STRING;
+- port_scanread : STRING;
+- port_scanwrite : STRING;
+- port_clk0 : STRING;
+- port_clk1 : STRING;
+- port_clk2 : STRING;
+- port_clk3 : STRING;
+- port_clk4 : STRING;
+- port_clk5 : STRING;
+- port_clkena0 : STRING;
+- port_clkena1 : STRING;
+- port_clkena2 : STRING;
+- port_clkena3 : STRING;
+- port_clkena4 : STRING;
+- port_clkena5 : STRING;
+- port_extclk0 : STRING;
+- port_extclk1 : STRING;
+- port_extclk2 : STRING;
+- port_extclk3 : STRING;
+- valid_lock_multiplier : NATURAL
+- );
+- PORT (
+- inclk : IN STD_LOGIC_VECTOR (1 DOWNTO 0);
+- locked : OUT STD_LOGIC ;
+- areset : IN STD_LOGIC ;
+- clk : OUT STD_LOGIC_VECTOR (5 DOWNTO 0)
+- );
+- END COMPONENT;
+-
+-BEGIN
+- sub_wire5_bv(0 DOWNTO 0) <= "0";
+- sub_wire5 <= To_stdlogicvector(sub_wire5_bv);
+- sub_wire1 <= sub_wire0(0);
+- c0 <= sub_wire1;
+- locked <= sub_wire2;
+- sub_wire3 <= inclk0;
+- sub_wire4 <= sub_wire5(0 DOWNTO 0) & sub_wire3;
+-
+- altpll_component : altpll
+- GENERIC MAP (
+- clk0_divide_by => 3,
+- clk0_duty_cycle => 50,
+- clk0_multiply_by => 4,
+- clk0_phase_shift => "0",
+- compensate_clock => "CLK0",
+- gate_lock_signal => "NO",
+- inclk0_input_frequency => 41666,
+- intended_device_family => "Cyclone II",
+- invalid_lock_multiplier => 5,
+- lpm_hint => "CBX_MODULE_PREFIX=pll32",
+- lpm_type => "altpll",
+- operation_mode => "NORMAL",
+- port_activeclock => "PORT_UNUSED",
+- port_areset => "PORT_USED",
+- port_clkbad0 => "PORT_UNUSED",
+- port_clkbad1 => "PORT_UNUSED",
+- port_clkloss => "PORT_UNUSED",
+- port_clkswitch => "PORT_UNUSED",
+- port_configupdate => "PORT_UNUSED",
+- port_fbin => "PORT_UNUSED",
+- port_inclk0 => "PORT_USED",
+- port_inclk1 => "PORT_UNUSED",
+- port_locked => "PORT_USED",
+- port_pfdena => "PORT_UNUSED",
+- port_phasecounterselect => "PORT_UNUSED",
+- port_phasedone => "PORT_UNUSED",
+- port_phasestep => "PORT_UNUSED",
+- port_phaseupdown => "PORT_UNUSED",
+- port_pllena => "PORT_UNUSED",
+- port_scanaclr => "PORT_UNUSED",
+- port_scanclk => "PORT_UNUSED",
+- port_scanclkena => "PORT_UNUSED",
+- port_scandata => "PORT_UNUSED",
+- port_scandataout => "PORT_UNUSED",
+- port_scandone => "PORT_UNUSED",
+- port_scanread => "PORT_UNUSED",
+- port_scanwrite => "PORT_UNUSED",
+- port_clk0 => "PORT_USED",
+- port_clk1 => "PORT_UNUSED",
+- port_clk2 => "PORT_UNUSED",
+- port_clk3 => "PORT_UNUSED",
+- port_clk4 => "PORT_UNUSED",
+- port_clk5 => "PORT_UNUSED",
+- port_clkena0 => "PORT_UNUSED",
+- port_clkena1 => "PORT_UNUSED",
+- port_clkena2 => "PORT_UNUSED",
+- port_clkena3 => "PORT_UNUSED",
+- port_clkena4 => "PORT_UNUSED",
+- port_clkena5 => "PORT_UNUSED",
+- port_extclk0 => "PORT_UNUSED",
+- port_extclk1 => "PORT_UNUSED",
+- port_extclk2 => "PORT_UNUSED",
+- port_extclk3 => "PORT_UNUSED",
+- valid_lock_multiplier => 1
+- )
+- PORT MAP (
+- inclk => sub_wire4,
+- areset => areset,
+- clk => sub_wire0,
+- locked => sub_wire2
+- );
+-
+-
+-
+-END SYN;
+-
+--- ============================================================
+--- CNX file retrieval info
+--- ============================================================
+--- Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
+--- Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
+--- Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "0"
+--- Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
+--- Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
+--- Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
+--- Retrieval info: PRIVATE: BANDWIDTH_USE_CUSTOM STRING "0"
+--- Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
+--- Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
+--- Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
+--- Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "1"
+--- Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
+--- Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
+--- Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
+--- Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
+--- Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "e0"
+--- Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "7"
+--- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
+--- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
+--- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "32.000000"
+--- Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
+--- Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
+--- Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
+--- Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "1"
+--- Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
+--- Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
+--- Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
+--- Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "24.000"
+--- Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
+--- Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
+--- Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
+--- Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
+--- Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
+--- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
+--- Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
+--- Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1"
+--- Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
+--- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "312.000"
+--- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
+--- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
+--- Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
+--- Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
+--- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1"
+--- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
+--- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "32.00000000"
+--- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
+--- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
+--- Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "0"
+--- Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
+--- Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
+--- Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
+--- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
+--- Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
+--- Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "1"
+--- Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
+--- Retrieval info: PRIVATE: PLL_ENA_CHECK STRING "0"
+--- Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
+--- Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
+--- Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
+--- Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
+--- Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
+--- Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
+--- Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
+--- Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll32.mif"
+--- Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
+--- Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "0"
+--- Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0"
+--- Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
+--- Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
+--- Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
+--- Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
+--- Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
+--- Retrieval info: PRIVATE: SPREAD_USE STRING "0"
+--- Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
+--- Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
+--- Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
+--- Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
+--- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
+--- Retrieval info: PRIVATE: USE_CLK0 STRING "1"
+--- Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
+--- Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
+--- Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
+--- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
+--- Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "3"
+--- Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
+--- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "4"
+--- Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
+--- Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
+--- Retrieval info: CONSTANT: GATE_LOCK_SIGNAL STRING "NO"
+--- Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "41666"
+--- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
+--- Retrieval info: CONSTANT: INVALID_LOCK_MULTIPLIER NUMERIC "5"
+--- Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
+--- Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
+--- Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_USED"
+--- Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
+--- Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED"
+--- Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
+--- Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
+--- Retrieval info: CONSTANT: VALID_LOCK_MULTIPLIER NUMERIC "1"
+--- Retrieval info: USED_PORT: @clk 0 0 6 0 OUTPUT_CLK_EXT VCC "@clk[5..0]"
+--- Retrieval info: USED_PORT: @extclk 0 0 4 0 OUTPUT_CLK_EXT VCC "@extclk[3..0]"
+--- Retrieval info: USED_PORT: @inclk 0 0 2 0 INPUT_CLK_EXT VCC "@inclk[1..0]"
+--- Retrieval info: USED_PORT: areset 0 0 0 0 INPUT GND "areset"
+--- Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
+--- Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
+--- Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked"
+--- Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
+--- Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
+--- Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
+--- Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
+--- Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0
+--- Retrieval info: GEN_FILE: TYPE_NORMAL pll32.vhd TRUE
+--- Retrieval info: GEN_FILE: TYPE_NORMAL pll32.ppf TRUE
+--- Retrieval info: GEN_FILE: TYPE_NORMAL pll32.inc FALSE
+--- Retrieval info: GEN_FILE: TYPE_NORMAL pll32.cmp FALSE
+--- Retrieval info: GEN_FILE: TYPE_NORMAL pll32.bsf FALSE
+--- Retrieval info: GEN_FILE: TYPE_NORMAL pll32_inst.vhd FALSE
+--- Retrieval info: LIB_FILE: altera_mf
+--- Retrieval info: CBX_MODULE_PREFIX: ON
++-- megafunction wizard: %ALTPLL%
++-- GENERATION: STANDARD
++-- VERSION: WM1.0
++-- MODULE: altpll
++
++-- ============================================================
++-- File Name: pll32.vhd
++-- Megafunction Name(s):
++-- altpll
++--
++-- Simulation Library Files(s):
++-- altera_mf
++-- ============================================================
++-- ************************************************************
++-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
++--
++-- 9.1 Build 222 10/21/2009 SJ Web Edition
++-- ************************************************************
++
++
++--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.
++
++
++LIBRARY ieee;
++USE ieee.std_logic_1164.all;
++
++LIBRARY altera_mf;
++USE altera_mf.all;
++
++ENTITY pll32 IS
++ PORT
++ (
++ areset : IN STD_LOGIC := '0';
++ inclk0 : IN STD_LOGIC := '0';
++ c0 : OUT STD_LOGIC ;
++ locked : OUT STD_LOGIC
++ );
++END pll32;
++
++
++ARCHITECTURE SYN OF pll32 IS
++
++ SIGNAL sub_wire0 : STD_LOGIC_VECTOR (5 DOWNTO 0);
++ SIGNAL sub_wire1 : STD_LOGIC ;
++ SIGNAL sub_wire2 : STD_LOGIC ;
++ SIGNAL sub_wire3 : STD_LOGIC ;
++ SIGNAL sub_wire4 : STD_LOGIC_VECTOR (1 DOWNTO 0);
++ SIGNAL sub_wire5_bv : BIT_VECTOR (0 DOWNTO 0);
++ SIGNAL sub_wire5 : STD_LOGIC_VECTOR (0 DOWNTO 0);
++
++
++
++ COMPONENT altpll
++ GENERIC (
++ clk0_divide_by : NATURAL;
++ clk0_duty_cycle : NATURAL;
++ clk0_multiply_by : NATURAL;
++ clk0_phase_shift : STRING;
++ compensate_clock : STRING;
++ gate_lock_signal : STRING;
++ inclk0_input_frequency : NATURAL;
++ intended_device_family : STRING;
++ invalid_lock_multiplier : NATURAL;
++ lpm_hint : STRING;
++ lpm_type : STRING;
++ operation_mode : STRING;
++ port_activeclock : STRING;
++ port_areset : STRING;
++ port_clkbad0 : STRING;
++ port_clkbad1 : STRING;
++ port_clkloss : STRING;
++ port_clkswitch : STRING;
++ port_configupdate : STRING;
++ port_fbin : STRING;
++ port_inclk0 : STRING;
++ port_inclk1 : STRING;
++ port_locked : STRING;
++ port_pfdena : STRING;
++ port_phasecounterselect : STRING;
++ port_phasedone : STRING;
++ port_phasestep : STRING;
++ port_phaseupdown : STRING;
++ port_pllena : STRING;
++ port_scanaclr : STRING;
++ port_scanclk : STRING;
++ port_scanclkena : STRING;
++ port_scandata : STRING;
++ port_scandataout : STRING;
++ port_scandone : STRING;
++ port_scanread : STRING;
++ port_scanwrite : STRING;
++ port_clk0 : STRING;
++ port_clk1 : STRING;
++ port_clk2 : STRING;
++ port_clk3 : STRING;
++ port_clk4 : STRING;
++ port_clk5 : STRING;
++ port_clkena0 : STRING;
++ port_clkena1 : STRING;
++ port_clkena2 : STRING;
++ port_clkena3 : STRING;
++ port_clkena4 : STRING;
++ port_clkena5 : STRING;
++ port_extclk0 : STRING;
++ port_extclk1 : STRING;
++ port_extclk2 : STRING;
++ port_extclk3 : STRING;
++ valid_lock_multiplier : NATURAL
++ );
++ PORT (
++ inclk : IN STD_LOGIC_VECTOR (1 DOWNTO 0);
++ locked : OUT STD_LOGIC ;
++ areset : IN STD_LOGIC ;
++ clk : OUT STD_LOGIC_VECTOR (5 DOWNTO 0)
++ );
++ END COMPONENT;
++
++BEGIN
++ sub_wire5_bv(0 DOWNTO 0) <= "0";
++ sub_wire5 <= To_stdlogicvector(sub_wire5_bv);
++ sub_wire1 <= sub_wire0(0);
++ c0 <= sub_wire1;
++ locked <= sub_wire2;
++ sub_wire3 <= inclk0;
++ sub_wire4 <= sub_wire5(0 DOWNTO 0) & sub_wire3;
++
++ altpll_component : altpll
++ GENERIC MAP (
++ clk0_divide_by => 3,
++ clk0_duty_cycle => 50,
++ clk0_multiply_by => 4,
++ clk0_phase_shift => "0",
++ compensate_clock => "CLK0",
++ gate_lock_signal => "NO",
++ inclk0_input_frequency => 41666,
++ intended_device_family => "Cyclone II",
++ invalid_lock_multiplier => 5,
++ lpm_hint => "CBX_MODULE_PREFIX=pll32",
++ lpm_type => "altpll",
++ operation_mode => "NORMAL",
++ port_activeclock => "PORT_UNUSED",
++ port_areset => "PORT_USED",
++ port_clkbad0 => "PORT_UNUSED",
++ port_clkbad1 => "PORT_UNUSED",
++ port_clkloss => "PORT_UNUSED",
++ port_clkswitch => "PORT_UNUSED",
++ port_configupdate => "PORT_UNUSED",
++ port_fbin => "PORT_UNUSED",
++ port_inclk0 => "PORT_USED",
++ port_inclk1 => "PORT_UNUSED",
++ port_locked => "PORT_USED",
++ port_pfdena => "PORT_UNUSED",
++ port_phasecounterselect => "PORT_UNUSED",
++ port_phasedone => "PORT_UNUSED",
++ port_phasestep => "PORT_UNUSED",
++ port_phaseupdown => "PORT_UNUSED",
++ port_pllena => "PORT_UNUSED",
++ port_scanaclr => "PORT_UNUSED",
++ port_scanclk => "PORT_UNUSED",
++ port_scanclkena => "PORT_UNUSED",
++ port_scandata => "PORT_UNUSED",
++ port_scandataout => "PORT_UNUSED",
++ port_scandone => "PORT_UNUSED",
++ port_scanread => "PORT_UNUSED",
++ port_scanwrite => "PORT_UNUSED",
++ port_clk0 => "PORT_USED",
++ port_clk1 => "PORT_UNUSED",
++ port_clk2 => "PORT_UNUSED",
++ port_clk3 => "PORT_UNUSED",
++ port_clk4 => "PORT_UNUSED",
++ port_clk5 => "PORT_UNUSED",
++ port_clkena0 => "PORT_UNUSED",
++ port_clkena1 => "PORT_UNUSED",
++ port_clkena2 => "PORT_UNUSED",
++ port_clkena3 => "PORT_UNUSED",
++ port_clkena4 => "PORT_UNUSED",
++ port_clkena5 => "PORT_UNUSED",
++ port_extclk0 => "PORT_UNUSED",
++ port_extclk1 => "PORT_UNUSED",
++ port_extclk2 => "PORT_UNUSED",
++ port_extclk3 => "PORT_UNUSED",
++ valid_lock_multiplier => 1
++ )
++ PORT MAP (
++ inclk => sub_wire4,
++ areset => areset,
++ clk => sub_wire0,
++ locked => sub_wire2
++ );
++
++
++
++END SYN;
++
++-- ============================================================
++-- CNX file retrieval info
++-- ============================================================
++-- Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
++-- Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
++-- Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "0"
++-- Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
++-- Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
++-- Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
++-- Retrieval info: PRIVATE: BANDWIDTH_USE_CUSTOM STRING "0"
++-- Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
++-- Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
++-- Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
++-- Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "1"
++-- Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
++-- Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
++-- Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
++-- Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
++-- Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "e0"
++-- Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "7"
++-- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
++-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
++-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "32.000000"
++-- Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
++-- Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
++-- Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
++-- Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "1"
++-- Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
++-- Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
++-- Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
++-- Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "24.000"
++-- Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
++-- Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
++-- Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
++-- Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
++-- Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
++-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
++-- Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
++-- Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1"
++-- Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
++-- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "312.000"
++-- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
++-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
++-- Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
++-- Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
++-- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1"
++-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
++-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "32.00000000"
++-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
++-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
++-- Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "0"
++-- Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
++-- Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
++-- Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
++-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
++-- Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
++-- Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "1"
++-- Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
++-- Retrieval info: PRIVATE: PLL_ENA_CHECK STRING "0"
++-- Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
++-- Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
++-- Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
++-- Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
++-- Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
++-- Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
++-- Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
++-- Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll32.mif"
++-- Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
++-- Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "0"
++-- Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0"
++-- Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
++-- Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
++-- Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
++-- Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
++-- Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
++-- Retrieval info: PRIVATE: SPREAD_USE STRING "0"
++-- Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
++-- Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
++-- Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
++-- Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
++-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
++-- Retrieval info: PRIVATE: USE_CLK0 STRING "1"
++-- Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
++-- Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
++-- Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
++-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
++-- Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "3"
++-- Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
++-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "4"
++-- Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
++-- Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
++-- Retrieval info: CONSTANT: GATE_LOCK_SIGNAL STRING "NO"
++-- Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "41666"
++-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
++-- Retrieval info: CONSTANT: INVALID_LOCK_MULTIPLIER NUMERIC "5"
++-- Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
++-- Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
++-- Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_USED"
++-- Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
++-- Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED"
++-- Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
++-- Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
++-- Retrieval info: CONSTANT: VALID_LOCK_MULTIPLIER NUMERIC "1"
++-- Retrieval info: USED_PORT: @clk 0 0 6 0 OUTPUT_CLK_EXT VCC "@clk[5..0]"
++-- Retrieval info: USED_PORT: @extclk 0 0 4 0 OUTPUT_CLK_EXT VCC "@extclk[3..0]"
++-- Retrieval info: USED_PORT: @inclk 0 0 2 0 INPUT_CLK_EXT VCC "@inclk[1..0]"
++-- Retrieval info: USED_PORT: areset 0 0 0 0 INPUT GND "areset"
++-- Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
++-- Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
++-- Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked"
++-- Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
++-- Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
++-- Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
++-- Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
++-- Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0
++-- Retrieval info: GEN_FILE: TYPE_NORMAL pll32.vhd TRUE
++-- Retrieval info: GEN_FILE: TYPE_NORMAL pll32.ppf TRUE
++-- Retrieval info: GEN_FILE: TYPE_NORMAL pll32.inc FALSE
++-- Retrieval info: GEN_FILE: TYPE_NORMAL pll32.cmp FALSE
++-- Retrieval info: GEN_FILE: TYPE_NORMAL pll32.bsf FALSE
++-- Retrieval info: GEN_FILE: TYPE_NORMAL pll32_inst.vhd FALSE
++-- Retrieval info: LIB_FILE: altera_mf
++-- Retrieval info: CBX_MODULE_PREFIX: ON
+diff --git a/ps2_intf.vhd b/ps2_intf.vhd
+index dc8440f..015a7d0 100644
+--- a/ps2_intf.vhd
++++ b/ps2_intf.vhd
+@@ -1,157 +1,157 @@
+--- ZX Spectrum for Altera DE1
+---
+--- Copyright (c) 2009-2011 Mike Stirling
+---
+--- 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 agreement from the author.
+---
+--- * License is granted for non-commercial use only. A fee may not be charged
+--- for redistributions as source code or in synthesized/hardware form without
+--- specific prior written agreement from the author.
+---
+--- 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.
+---
+-
+--- PS/2 interface (input only)
+--- Based loosely on ps2_ctrl.vhd (c) ALSE. http://www.alse-fr.com
+-library IEEE;
+-use IEEE.STD_LOGIC_1164.ALL;
+-use IEEE.NUMERIC_STD.ALL;
+-
+--- This is input-only for the time being
+-entity ps2_intf is
+-generic (filter_length : positive := 8);
+-port(
+- CLK : in std_logic;
+- nRESET : in std_logic;
+-
+- -- PS/2 interface (could be bi-dir)
+- PS2_CLK : in std_logic;
+- PS2_DATA : in std_logic;
+-
+- -- Byte-wide data interface - only valid for one clock
+- -- so must be latched externally if required
+- DATA : out std_logic_vector(7 downto 0);
+- VALID : out std_logic;
+- ERROR : out std_logic
+- );
+-end ps2_intf;
+-
+-architecture ps2_intf_arch of ps2_intf is
+-subtype filter_t is std_logic_vector(filter_length-1 downto 0);
+-signal clk_filter : filter_t;
+-
+-signal ps2_clk_in : std_logic;
+-signal ps2_dat_in : std_logic;
+--- Goes high when a clock falling edge is detected
+-signal clk_edge : std_logic;
+-signal bit_count : unsigned (3 downto 0);
+-signal shiftreg : std_logic_vector(8 downto 0);
+-signal parity : std_logic;
+-begin
+- -- Register input signals
+- process(nRESET,CLK)
+- begin
+- if nRESET = '0' then
+- ps2_clk_in <= '1';
+- ps2_dat_in <= '1';
+- clk_filter <= (others => '1');
+- clk_edge <= '0';
+- elsif rising_edge(CLK) then
+- -- Register inputs (and filter clock)
+- ps2_dat_in <= PS2_DATA;
+- clk_filter <= PS2_CLK & clk_filter(clk_filter'high downto 1);
+- clk_edge <= '0';
+-
+- if clk_filter = filter_t'(others => '1') then
+- -- Filtered clock is high
+- ps2_clk_in <= '1';
+- elsif clk_filter = filter_t'(others => '0') then
+- -- Filter clock is low, check for edge
+- if ps2_clk_in = '1' then
+- clk_edge <= '1';
+- end if;
+- ps2_clk_in <= '0';
+- end if;
+- end if;
+- end process;
+-
+- -- Shift in keyboard data
+- process(nRESET,CLK)
+- begin
+- if nRESET = '0' then
+- bit_count <= (others => '0');
+- shiftreg <= (others => '0');
+- parity <= '0';
+- DATA <= (others => '0');
+- VALID <= '0';
+- ERROR <= '0';
+- elsif rising_edge(CLK) then
+- -- Clear flags
+- VALID <= '0';
+- ERROR <= '0';
+-
+- if clk_edge = '1' then
+- -- We have a new bit from the keyboard for processing
+- if bit_count = 0 then
+- -- Idle state, check for start bit (0) only and don't
+- -- start counting bits until we get it
+-
+- parity <= '0';
+-
+- if ps2_dat_in = '0' then
+- -- This is a start bit
+- bit_count <= bit_count + 1;
+- end if;
+- else
+- -- Running. 8-bit data comes in LSb first followed by
+- -- a single stop bit (1)
+- if bit_count < 10 then
+- -- Shift in data and parity (9 bits)
+- bit_count <= bit_count + 1;
+- shiftreg <= ps2_dat_in & shiftreg(shiftreg'high downto 1);
+- parity <= parity xor ps2_dat_in; -- Calculate parity
+- elsif ps2_dat_in = '1' then
+- -- Valid stop bit received
+- bit_count <= (others => '0'); -- back to idle
+- if parity = '1' then
+- -- Parity correct, submit data to host
+- DATA <= shiftreg(7 downto 0);
+- VALID <= '1';
+- else
+- -- Error
+- ERROR <= '1';
+- end if;
+- else
+- -- Invalid stop bit
+- bit_count <= (others => '0'); -- back to idle
+- ERROR <= '1';
+- end if;
+- end if;
+- end if;
+- end if;
+- end process;
+-end ps2_intf_arch;
++-- ZX Spectrum for Altera DE1
++--
++-- Copyright (c) 2009-2011 Mike Stirling
++--
++-- 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 agreement from the author.
++--
++-- * License is granted for non-commercial use only. A fee may not be charged
++-- for redistributions as source code or in synthesized/hardware form without
++-- specific prior written agreement from the author.
++--
++-- 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.
++--
++
++-- PS/2 interface (input only)
++-- Based loosely on ps2_ctrl.vhd (c) ALSE. http://www.alse-fr.com
++library IEEE;
++use IEEE.STD_LOGIC_1164.ALL;
++use IEEE.NUMERIC_STD.ALL;
++
++-- This is input-only for the time being
++entity ps2_intf is
++generic (filter_length : positive := 8);
++port(
++ CLK : in std_logic;
++ nRESET : in std_logic;
++
++ -- PS/2 interface (could be bi-dir)
++ PS2_CLK : in std_logic;
++ PS2_DATA : in std_logic;
++
++ -- Byte-wide data interface - only valid for one clock
++ -- so must be latched externally if required
++ DATA : out std_logic_vector(7 downto 0);
++ VALID : out std_logic;
++ ERROR : out std_logic
++ );
++end ps2_intf;
++
++architecture ps2_intf_arch of ps2_intf is
++subtype filter_t is std_logic_vector(filter_length-1 downto 0);
++signal clk_filter : filter_t;
++
++signal ps2_clk_in : std_logic;
++signal ps2_dat_in : std_logic;
++-- Goes high when a clock falling edge is detected
++signal clk_edge : std_logic;
++signal bit_count : unsigned (3 downto 0);
++signal shiftreg : std_logic_vector(8 downto 0);
++signal parity : std_logic;
++begin
++ -- Register input signals
++ process(nRESET,CLK)
++ begin
++ if nRESET = '0' then
++ ps2_clk_in <= '1';
++ ps2_dat_in <= '1';
++ clk_filter <= (others => '1');
++ clk_edge <= '0';
++ elsif rising_edge(CLK) then
++ -- Register inputs (and filter clock)
++ ps2_dat_in <= PS2_DATA;
++ clk_filter <= PS2_CLK & clk_filter(clk_filter'high downto 1);
++ clk_edge <= '0';
++
++ if clk_filter = filter_t'(others => '1') then
++ -- Filtered clock is high
++ ps2_clk_in <= '1';
++ elsif clk_filter = filter_t'(others => '0') then
++ -- Filter clock is low, check for edge
++ if ps2_clk_in = '1' then
++ clk_edge <= '1';
++ end if;
++ ps2_clk_in <= '0';
++ end if;
++ end if;
++ end process;
++
++ -- Shift in keyboard data
++ process(nRESET,CLK)
++ begin
++ if nRESET = '0' then
++ bit_count <= (others => '0');
++ shiftreg <= (others => '0');
++ parity <= '0';
++ DATA <= (others => '0');
++ VALID <= '0';
++ ERROR <= '0';
++ elsif rising_edge(CLK) then
++ -- Clear flags
++ VALID <= '0';
++ ERROR <= '0';
++
++ if clk_edge = '1' then
++ -- We have a new bit from the keyboard for processing
++ if bit_count = 0 then
++ -- Idle state, check for start bit (0) only and don't
++ -- start counting bits until we get it
++
++ parity <= '0';
++
++ if ps2_dat_in = '0' then
++ -- This is a start bit
++ bit_count <= bit_count + 1;
++ end if;
++ else
++ -- Running. 8-bit data comes in LSb first followed by
++ -- a single stop bit (1)
++ if bit_count < 10 then
++ -- Shift in data and parity (9 bits)
++ bit_count <= bit_count + 1;
++ shiftreg <= ps2_dat_in & shiftreg(shiftreg'high downto 1);
++ parity <= parity xor ps2_dat_in; -- Calculate parity
++ elsif ps2_dat_in = '1' then
++ -- Valid stop bit received
++ bit_count <= (others => '0'); -- back to idle
++ if parity = '1' then
++ -- Parity correct, submit data to host
++ DATA <= shiftreg(7 downto 0);
++ VALID <= '1';
++ else
++ -- Error
++ ERROR <= '1';
++ end if;
++ else
++ -- Invalid stop bit
++ bit_count <= (others => '0'); -- back to idle
++ ERROR <= '1';
++ end if;
++ end if;
++ end if;
++ end if;
++ end process;
++end ps2_intf_arch;
+diff --git a/saa5050.vhd b/saa5050.vhd
+index 57dd999..f198aa8 100644
+--- a/saa5050.vhd
++++ b/saa5050.vhd
+@@ -1,391 +1,391 @@
+--- BBC Micro for Altera DE1
+---
+--- Copyright (c) 2011 Mike Stirling
+---
+--- 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 agreement from the author.
+---
+--- * License is granted for non-commercial use only. A fee may not be charged
+--- for redistributions as source code or in synthesized/hardware form without
+--- specific prior written agreement from the author.
+---
+--- 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.
+---
+--- SAA5050 teletext generator
+---
+--- Synchronous implementation for FPGA. Certain TV-specific functions are
+--- not implemented. e.g.
+---
+--- No /SI pin - 'TEXT' mode is permanently enabled
+--- No remote control features (/DATA, DLIM)
+--- No large character support
+--- No support for box overlay (BLAN, PO, DE)
+--- No character rounding, although this may be added
+---
+--- FIXME: Hold graphics not supported - this needs to be added
+---
+--- (C) 2011 Mike Stirling
+---
+-library IEEE;
+-use IEEE.STD_LOGIC_1164.ALL;
+-use IEEE.NUMERIC_STD.ALL;
+-
+-entity saa5050 is
+-port (
+- CLOCK : in std_logic;
+- -- 6 MHz dot clock enable
+- CLKEN : in std_logic;
+- -- Async reset
+- nRESET : in std_logic;
+-
+- -- Character data input (in the bus clock domain)
+- DI_CLOCK : in std_logic;
+- DI_CLKEN : in std_logic;
+- DI : in std_logic_vector(6 downto 0);
+-
+- -- Timing inputs
+- -- General line reset (not used)
+- GLR : in std_logic; -- /HSYNC
+- -- Data entry window - high during VSYNC.
+- -- Resets ROM row counter and drives 'flash' signal
+- DEW : in std_logic; -- VSYNC
+- -- Character rounding select - high during even field
+- CRS : in std_logic; -- FIELD
+- -- Load output shift register enable - high during active video
+- LOSE : in std_logic; -- DE
+-
+- -- Video out
+- R : out std_logic;
+- G : out std_logic;
+- B : out std_logic;
+- Y : out std_logic
+- );
+-end entity;
+-
+-architecture rtl of saa5050 is
+-
+-component saa5050_rom IS
+- PORT
+- (
+- address : IN STD_LOGIC_VECTOR (11 DOWNTO 0);
+- clock : IN STD_LOGIC ;
+- q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
+- );
+-end component;
+-
+--- Register inputs in the bus clock domain
+-signal di_r : std_logic_vector(6 downto 0);
+-signal dew_r : std_logic;
+-signal lose_r : std_logic;
+--- Data input registered in the pixel clock domain
+-signal code : std_logic_vector(6 downto 0);
+-signal line_addr : unsigned(3 downto 0);
+-signal rom_address : std_logic_vector(11 downto 0);
+-signal rom_data : std_logic_vector(7 downto 0);
+-
+--- Delayed display enable derived from LOSE by delaying for one character
+-signal disp_enable : std_logic;
+--- Latched timing signals for detection of falling edges
+-signal dew_latch : std_logic;
+-signal lose_latch : std_logic;
+-signal disp_enable_latch : std_logic;
+-
+--- Row and column addressing is handled externally. We just need to
+--- keep track of which of the 10 lines we are on within the character...
+-signal line_counter : unsigned(3 downto 0);
+--- ... and which of the 6 pixels we are on within each line
+-signal pixel_counter : unsigned(2 downto 0);
+--- We also need to count frames to implement the flash feature.
+--- The datasheet says this is 0.75 Hz with a 3:1 on/off ratio, so it
+--- is probably a /64 counter, which gives us 0.78 Hz
+-signal flash_counter : unsigned(5 downto 0);
+--- Output shift register
+-signal shift_reg : std_logic_vector(5 downto 0);
+-
+--- Flash mask
+-signal flash : std_logic;
+-
+--- Current display state
+--- Foreground colour (B2, G1, R0)
+-signal fg : std_logic_vector(2 downto 0);
+--- Background colour (B2, G1, R0)
+-signal bg : std_logic_vector(2 downto 0);
+-signal conceal : std_logic;
+-signal gfx : std_logic;
+-signal gfx_sep : std_logic;
+-signal gfx_hold : std_logic;
+-signal is_flash : std_logic;
+-signal double_high : std_logic;
+--- Set in first row of double height
+-signal double_high1 : std_logic;
+--- Set in second row of double height
+-signal double_high2 : std_logic;
+-
+-begin
+- char_rom: saa5050_rom port map (
+- rom_address,
+- CLOCK,
+- rom_data
+- );
+-
+- -- Generate flash signal for 3:1 ratio
+- flash <= flash_counter(5) and flash_counter(4);
+-
+- -- Sync inputs
+- process(DI_CLOCK,nRESET)
+- begin
+- if nRESET = '0' then
+- di_r <= (others => '0');
+- dew_r <= '0';
+- lose_r <= '0';
+- elsif rising_edge(DI_CLOCK) and DI_CLKEN = '1' then
+- di_r <= DI;
+- dew_r <= DEW;
+- lose_r <= LOSE;
+- end if;
+- end process;
+-
+- -- Register data into pixel clock domain
+- process(CLOCK,nRESET)
+- begin
+- if nRESET = '0' then
+- code <= (others => '0');
+- elsif rising_edge(CLOCK) and CLKEN = '1' then
+- code <= di_r;
+- end if;
+- end process;
+-
+- -- Generate character rom address in pixel clock domain
+- -- This is done combinatorially since all the inputs are already
+- -- registered and the address is re-registered by the ROM
+- line_addr <= line_counter when double_high = '0' else
+- ("0" & line_counter(3 downto 1)) when double_high2 = '0' else
+- ("0" & line_counter(3 downto 1)) + 5;
+- rom_address <= (others => '0') when (double_high = '0' and double_high2 = '1') else
+- gfx & code & std_logic_vector(line_addr);
+-
+- -- Character row and pixel counters
+- process(CLOCK,nRESET)
+- begin
+- if nRESET = '0' then
+- dew_latch <= '0';
+- lose_latch <= '0';
+- disp_enable <= '0';
+- disp_enable_latch <= '0';
+- double_high1 <= '0';
+- double_high2 <= '0';
+- line_counter <= (others => '0');
+- pixel_counter <= (others => '0');
+- flash_counter <= (others => '0');
+- elsif rising_edge(CLOCK) and CLKEN = '1' then
+- -- Register syncs for edge detection
+- dew_latch <= dew_r;
+- lose_latch <= lose_r;
+- disp_enable_latch <= disp_enable;
+-
+- -- When first entering double-height mode start on top row
+- if double_high = '1' and double_high1 = '0' and double_high2 = '0' then
+- double_high1 <= '1';
+- end if;
+-
+- -- Count pixels between 0 and 5
+- if pixel_counter = 5 then
+- -- Start of next character and delayed display enable
+- pixel_counter <= (others => '0');
+- disp_enable <= lose_latch;
+- else
+- pixel_counter <= pixel_counter + 1;
+- end if;
+-
+- -- Rising edge of LOSE is the start of the active line
+- if lose_r = '1' and lose_latch = '0' then
+- -- Reset pixel counter - small offset to make the output
+- -- line up with the cursor from the video ULA
+- pixel_counter <= "011";
+- end if;
+-
+- -- Count frames on end of VSYNC (falling edge of DEW)
+- if dew_r = '0' and dew_latch = '1' then
+- flash_counter <= flash_counter + 1;
+- end if;
+-
+- if dew_r = '1' then
+- -- Reset line counter and double height state during VSYNC
+- line_counter <= (others => '0');
+- double_high1 <= '0';
+- double_high2 <= '0';
+- else
+- -- Count lines on end of active video (falling edge of disp_enable)
+- if disp_enable = '0' and disp_enable_latch = '1' then
+- if line_counter = 9 then
+- line_counter <= (others => '0');
+-
+- -- Keep track of which row we are on for double-height
+- -- The double_high flag can be cleared before the end of a row, but if
+- -- double height characters are used anywhere on a row then the double_high1
+- -- flag will be set and remain set until the next row. This is used
+- -- to determine that the bottom half of the characters should be shown if
+- -- double_high is set once again on the row below.
+- double_high1 <= '0';
+- double_high2 <= double_high1;
+- else
+- line_counter <= line_counter + 1;
+- end if;
+- end if;
+- end if;
+- end if;
+- end process;
+-
+- -- Shift register
+- process(CLOCK,nRESET)
+- begin
+- if nRESET = '0' then
+- shift_reg <= (others => '0');
+- elsif rising_edge(CLOCK) and CLKEN = '1' then
+- if disp_enable = '1' and pixel_counter = 0 then
+- -- Load the shift register with the ROM bit pattern
+- -- at the start of each character while disp_enable is asserted.
+- shift_reg <= rom_data(5 downto 0);
+-
+- -- If bit 7 of the ROM data is set then this is a graphics
+- -- character and separated/hold graphics modes apply.
+- -- We don't just assume this to be the case if gfx=1 because
+- -- these modes don't apply to caps even in graphics mode
+- if rom_data(7) = '1' then
+- -- Apply a mask for separated graphics mode
+- if gfx_sep = '1' then
+- shift_reg(5) <= '0';
+- shift_reg(2) <= '0';
+- if line_counter = 2 or line_counter = 6 or line_counter = 9 then
+- shift_reg <= (others => '0');
+- end if;
+- end if;
+- end if;
+- else
+- -- Pump the shift register
+- shift_reg <= shift_reg(4 downto 0) & "0";
+- end if;
+- end if;
+- end process;
+-
+- -- Control character handling
+- process(CLOCK,nRESET)
+- begin
+- if nRESET = '0' then
+- fg <= (others => '1');
+- bg <= (others => '0');
+- conceal <= '0';
+- gfx <= '0';
+- gfx_sep <= '0';
+- gfx_hold <= '0';
+- is_flash <= '0';
+- double_high <= '0';
+- elsif rising_edge(CLOCK) and CLKEN = '1' then
+- if disp_enable = '0' then
+- -- Reset to start of line defaults
+- fg <= (others => '1');
+- bg <= (others => '0');
+- conceal <= '0';
+- gfx <= '0';
+- gfx_sep <= '0';
+- gfx_hold <= '0';
+- is_flash <= '0';
+- double_high <= '0';
+- elsif pixel_counter = 0 then
+- -- Latch new control codes at the start of each character
+- if code(6 downto 5) = "00" then
+- if code(3) = '0' then
+- -- Colour and graphics setting clears conceal mode
+- conceal <= '0';
+-
+- -- Select graphics or alpha mode
+- gfx <= code(4);
+-
+- -- 0 would be black but is not allowed so has no effect,
+- -- otherwise set the colour
+- if code(2 downto 0) /= "000" then
+- fg <= code(2 downto 0);
+- end if;
+- else
+- case code(4 downto 0) is
+- -- FLASH
+- when "01000" => is_flash <= '1';
+- -- STEADY
+- when "01001" => is_flash <= '0';
+- -- NORMAL HEIGHT
+- when "01100" => double_high <= '0';
+- -- DOUBLE HEIGHT
+- when "01101" => double_high <= '1';
+- -- CONCEAL
+- when "11000" => conceal <= '1';
+- -- CONTIGUOUS GFX
+- when "11001" => gfx_sep <= '0';
+- -- SEPARATED GFX
+- when "11010" => gfx_sep <= '1';
+- -- BLACK BACKGROUND
+- when "11100" => bg <= (others => '0');
+- -- NEW BACKGROUND
+- when "11101" => bg <= fg;
+- -- HOLD GFX
+- when "11110" => gfx_hold <= '1';
+- -- RELEASE GFX
+- when "11111" => gfx_hold <= '0';
+-
+- when others => null;
+- end case;
+- end if;
+- end if;
+- end if;
+- end if;
+- end process;
+-
+- -- Output
+- process(CLOCK,nRESET)
+- variable pixel : std_logic;
+- begin
+- pixel := shift_reg(5) and not ((flash and is_flash) or conceal);
+-
+- if nRESET = '0' then
+- R <= '0';
+- G <= '0';
+- B <= '0';
+- elsif rising_edge(CLOCK) and CLKEN = '1' then
+- -- Generate mono output
+- Y <= pixel;
+-
+- -- Generate colour output
+- if pixel = '1' then
+- R <= fg(0);
+- G <= fg(1);
+- B <= fg(2);
+- else
+- R <= bg(0);
+- G <= bg(1);
+- B <= bg(2);
+- end if;
+- end if;
+- end process;
+-end architecture;
++-- BBC Micro for Altera DE1
++--
++-- Copyright (c) 2011 Mike Stirling
++--
++-- 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 agreement from the author.
++--
++-- * License is granted for non-commercial use only. A fee may not be charged
++-- for redistributions as source code or in synthesized/hardware form without
++-- specific prior written agreement from the author.
++--
++-- 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.
++--
++-- SAA5050 teletext generator
++--
++-- Synchronous implementation for FPGA. Certain TV-specific functions are
++-- not implemented. e.g.
++--
++-- No /SI pin - 'TEXT' mode is permanently enabled
++-- No remote control features (/DATA, DLIM)
++-- No large character support
++-- No support for box overlay (BLAN, PO, DE)
++-- No character rounding, although this may be added
++--
++-- FIXME: Hold graphics not supported - this needs to be added
++--
++-- (C) 2011 Mike Stirling
++--
++library IEEE;
++use IEEE.STD_LOGIC_1164.ALL;
++use IEEE.NUMERIC_STD.ALL;
++
++entity saa5050 is
++port (
++ CLOCK : in std_logic;
++ -- 6 MHz dot clock enable
++ CLKEN : in std_logic;
++ -- Async reset
++ nRESET : in std_logic;
++
++ -- Character data input (in the bus clock domain)
++ DI_CLOCK : in std_logic;
++ DI_CLKEN : in std_logic;
++ DI : in std_logic_vector(6 downto 0);
++
++ -- Timing inputs
++ -- General line reset (not used)
++ GLR : in std_logic; -- /HSYNC
++ -- Data entry window - high during VSYNC.
++ -- Resets ROM row counter and drives 'flash' signal
++ DEW : in std_logic; -- VSYNC
++ -- Character rounding select - high during even field
++ CRS : in std_logic; -- FIELD
++ -- Load output shift register enable - high during active video
++ LOSE : in std_logic; -- DE
++
++ -- Video out
++ R : out std_logic;
++ G : out std_logic;
++ B : out std_logic;
++ Y : out std_logic
++ );
++end entity;
++
++architecture rtl of saa5050 is
++
++component saa5050_rom IS
++ PORT
++ (
++ address : IN STD_LOGIC_VECTOR (11 DOWNTO 0);
++ clock : IN STD_LOGIC ;
++ q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
++ );
++end component;
++
++-- Register inputs in the bus clock domain
++signal di_r : std_logic_vector(6 downto 0);
++signal dew_r : std_logic;
++signal lose_r : std_logic;
++-- Data input registered in the pixel clock domain
++signal code : std_logic_vector(6 downto 0);
++signal line_addr : unsigned(3 downto 0);
++signal rom_address : std_logic_vector(11 downto 0);
++signal rom_data : std_logic_vector(7 downto 0);
++
++-- Delayed display enable derived from LOSE by delaying for one character
++signal disp_enable : std_logic;
++-- Latched timing signals for detection of falling edges
++signal dew_latch : std_logic;
++signal lose_latch : std_logic;
++signal disp_enable_latch : std_logic;
++
++-- Row and column addressing is handled externally. We just need to
++-- keep track of which of the 10 lines we are on within the character...
++signal line_counter : unsigned(3 downto 0);
++-- ... and which of the 6 pixels we are on within each line
++signal pixel_counter : unsigned(2 downto 0);
++-- We also need to count frames to implement the flash feature.
++-- The datasheet says this is 0.75 Hz with a 3:1 on/off ratio, so it
++-- is probably a /64 counter, which gives us 0.78 Hz
++signal flash_counter : unsigned(5 downto 0);
++-- Output shift register
++signal shift_reg : std_logic_vector(5 downto 0);
++
++-- Flash mask
++signal flash : std_logic;
++
++-- Current display state
++-- Foreground colour (B2, G1, R0)
++signal fg : std_logic_vector(2 downto 0);
++-- Background colour (B2, G1, R0)
++signal bg : std_logic_vector(2 downto 0);
++signal conceal : std_logic;
++signal gfx : std_logic;
++signal gfx_sep : std_logic;
++signal gfx_hold : std_logic;
++signal is_flash : std_logic;
++signal double_high : std_logic;
++-- Set in first row of double height
++signal double_high1 : std_logic;
++-- Set in second row of double height
++signal double_high2 : std_logic;
++
++begin
++ char_rom: saa5050_rom port map (
++ rom_address,
++ CLOCK,
++ rom_data
++ );
++
++ -- Generate flash signal for 3:1 ratio
++ flash <= flash_counter(5) and flash_counter(4);
++
++ -- Sync inputs
++ process(DI_CLOCK,nRESET)
++ begin
++ if nRESET = '0' then
++ di_r <= (others => '0');
++ dew_r <= '0';
++ lose_r <= '0';
++ elsif rising_edge(DI_CLOCK) and DI_CLKEN = '1' then
++ di_r <= DI;
++ dew_r <= DEW;
++ lose_r <= LOSE;
++ end if;
++ end process;
++
++ -- Register data into pixel clock domain
++ process(CLOCK,nRESET)
++ begin
++ if nRESET = '0' then
++ code <= (others => '0');
++ elsif rising_edge(CLOCK) and CLKEN = '1' then
++ code <= di_r;
++ end if;
++ end process;
++
++ -- Generate character rom address in pixel clock domain
++ -- This is done combinatorially since all the inputs are already
++ -- registered and the address is re-registered by the ROM
++ line_addr <= line_counter when double_high = '0' else
++ ("0" & line_counter(3 downto 1)) when double_high2 = '0' else
++ ("0" & line_counter(3 downto 1)) + 5;
++ rom_address <= (others => '0') when (double_high = '0' and double_high2 = '1') else
++ gfx & code & std_logic_vector(line_addr);
++
++ -- Character row and pixel counters
++ process(CLOCK,nRESET)
++ begin
++ if nRESET = '0' then
++ dew_latch <= '0';
++ lose_latch <= '0';
++ disp_enable <= '0';
++ disp_enable_latch <= '0';
++ double_high1 <= '0';
++ double_high2 <= '0';
++ line_counter <= (others => '0');
++ pixel_counter <= (others => '0');
++ flash_counter <= (others => '0');
++ elsif rising_edge(CLOCK) and CLKEN = '1' then
++ -- Register syncs for edge detection
++ dew_latch <= dew_r;
++ lose_latch <= lose_r;
++ disp_enable_latch <= disp_enable;
++
++ -- When first entering double-height mode start on top row
++ if double_high = '1' and double_high1 = '0' and double_high2 = '0' then
++ double_high1 <= '1';
++ end if;
++
++ -- Count pixels between 0 and 5
++ if pixel_counter = 5 then
++ -- Start of next character and delayed display enable
++ pixel_counter <= (others => '0');
++ disp_enable <= lose_latch;
++ else
++ pixel_counter <= pixel_counter + 1;
++ end if;
++
++ -- Rising edge of LOSE is the start of the active line
++ if lose_r = '1' and lose_latch = '0' then
++ -- Reset pixel counter - small offset to make the output
++ -- line up with the cursor from the video ULA
++ pixel_counter <= "011";
++ end if;
++
++ -- Count frames on end of VSYNC (falling edge of DEW)
++ if dew_r = '0' and dew_latch = '1' then
++ flash_counter <= flash_counter + 1;
++ end if;
++
++ if dew_r = '1' then
++ -- Reset line counter and double height state during VSYNC
++ line_counter <= (others => '0');
++ double_high1 <= '0';
++ double_high2 <= '0';
++ else
++ -- Count lines on end of active video (falling edge of disp_enable)
++ if disp_enable = '0' and disp_enable_latch = '1' then
++ if line_counter = 9 then
++ line_counter <= (others => '0');
++
++ -- Keep track of which row we are on for double-height
++ -- The double_high flag can be cleared before the end of a row, but if
++ -- double height characters are used anywhere on a row then the double_high1
++ -- flag will be set and remain set until the next row. This is used
++ -- to determine that the bottom half of the characters should be shown if
++ -- double_high is set once again on the row below.
++ double_high1 <= '0';
++ double_high2 <= double_high1;
++ else
++ line_counter <= line_counter + 1;
++ end if;
++ end if;
++ end if;
++ end if;
++ end process;
++
++ -- Shift register
++ process(CLOCK,nRESET)
++ begin
++ if nRESET = '0' then
++ shift_reg <= (others => '0');
++ elsif rising_edge(CLOCK) and CLKEN = '1' then
++ if disp_enable = '1' and pixel_counter = 0 then
++ -- Load the shift register with the ROM bit pattern
++ -- at the start of each character while disp_enable is asserted.
++ shift_reg <= rom_data(5 downto 0);
++
++ -- If bit 7 of the ROM data is set then this is a graphics
++ -- character and separated/hold graphics modes apply.
++ -- We don't just assume this to be the case if gfx=1 because
++ -- these modes don't apply to caps even in graphics mode
++ if rom_data(7) = '1' then
++ -- Apply a mask for separated graphics mode
++ if gfx_sep = '1' then
++ shift_reg(5) <= '0';
++ shift_reg(2) <= '0';
++ if line_counter = 2 or line_counter = 6 or line_counter = 9 then
++ shift_reg <= (others => '0');
++ end if;
++ end if;
++ end if;
++ else
++ -- Pump the shift register
++ shift_reg <= shift_reg(4 downto 0) & "0";
++ end if;
++ end if;
++ end process;
++
++ -- Control character handling
++ process(CLOCK,nRESET)
++ begin
++ if nRESET = '0' then
++ fg <= (others => '1');
++ bg <= (others => '0');
++ conceal <= '0';
++ gfx <= '0';
++ gfx_sep <= '0';
++ gfx_hold <= '0';
++ is_flash <= '0';
++ double_high <= '0';
++ elsif rising_edge(CLOCK) and CLKEN = '1' then
++ if disp_enable = '0' then
++ -- Reset to start of line defaults
++ fg <= (others => '1');
++ bg <= (others => '0');
++ conceal <= '0';
++ gfx <= '0';
++ gfx_sep <= '0';
++ gfx_hold <= '0';
++ is_flash <= '0';
++ double_high <= '0';
++ elsif pixel_counter = 0 then
++ -- Latch new control codes at the start of each character
++ if code(6 downto 5) = "00" then
++ if code(3) = '0' then
++ -- Colour and graphics setting clears conceal mode
++ conceal <= '0';
++
++ -- Select graphics or alpha mode
++ gfx <= code(4);
++
++ -- 0 would be black but is not allowed so has no effect,
++ -- otherwise set the colour
++ if code(2 downto 0) /= "000" then
++ fg <= code(2 downto 0);
++ end if;
++ else
++ case code(4 downto 0) is
++ -- FLASH
++ when "01000" => is_flash <= '1';
++ -- STEADY
++ when "01001" => is_flash <= '0';
++ -- NORMAL HEIGHT
++ when "01100" => double_high <= '0';
++ -- DOUBLE HEIGHT
++ when "01101" => double_high <= '1';
++ -- CONCEAL
++ when "11000" => conceal <= '1';
++ -- CONTIGUOUS GFX
++ when "11001" => gfx_sep <= '0';
++ -- SEPARATED GFX
++ when "11010" => gfx_sep <= '1';
++ -- BLACK BACKGROUND
++ when "11100" => bg <= (others => '0');
++ -- NEW BACKGROUND
++ when "11101" => bg <= fg;
++ -- HOLD GFX
++ when "11110" => gfx_hold <= '1';
++ -- RELEASE GFX
++ when "11111" => gfx_hold <= '0';
++
++ when others => null;
++ end case;
++ end if;
++ end if;
++ end if;
++ end if;
++ end process;
++
++ -- Output
++ process(CLOCK,nRESET)
++ variable pixel : std_logic;
++ begin
++ pixel := shift_reg(5) and not ((flash and is_flash) or conceal);
++
++ if nRESET = '0' then
++ R <= '0';
++ G <= '0';
++ B <= '0';
++ elsif rising_edge(CLOCK) and CLKEN = '1' then
++ -- Generate mono output
++ Y <= pixel;
++
++ -- Generate colour output
++ if pixel = '1' then
++ R <= fg(0);
++ G <= fg(1);
++ B <= fg(2);
++ else
++ R <= bg(0);
++ G <= bg(1);
++ B <= bg(2);
++ end if;
++ end if;
++ end process;
++end architecture;
+diff --git a/saa5050_rom.qip b/saa5050_rom.qip
+index e9513f7..be776f1 100644
+--- a/saa5050_rom.qip
++++ b/saa5050_rom.qip
+@@ -1,3 +1,3 @@
+-set_global_assignment -name IP_TOOL_NAME "ROM: 1-PORT"
+-set_global_assignment -name IP_TOOL_VERSION "9.1"
+-set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "saa5050_rom.vhd"]
++set_global_assignment -name IP_TOOL_NAME "ROM: 1-PORT"
++set_global_assignment -name IP_TOOL_VERSION "9.1"
++set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "saa5050_rom.vhd"]
+diff --git a/saa5050_rom.vhd b/saa5050_rom.vhd
+index 7541c0b..e1c702d 100644
+--- a/saa5050_rom.vhd
++++ b/saa5050_rom.vhd
+@@ -1,168 +1,168 @@
+--- megafunction wizard: %ROM: 1-PORT%
+--- GENERATION: STANDARD
+--- VERSION: WM1.0
+--- MODULE: altsyncram
+-
+--- ============================================================
+--- File Name: saa5050_rom.vhd
+--- Megafunction Name(s):
+--- altsyncram
+---
+--- Simulation Library Files(s):
+--- altera_mf
+--- ============================================================
+--- ************************************************************
+--- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+---
+--- 9.1 Build 222 10/21/2009 SJ Web Edition
+--- ************************************************************
+-
+-
+---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.
+-
+-
+-LIBRARY ieee;
+-USE ieee.std_logic_1164.all;
+-
+-LIBRARY altera_mf;
+-USE altera_mf.all;
+-
+-ENTITY saa5050_rom IS
+- PORT
+- (
+- address : IN STD_LOGIC_VECTOR (11 DOWNTO 0);
+- clock : IN STD_LOGIC ;
+- q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
+- );
+-END saa5050_rom;
+-
+-
+-ARCHITECTURE SYN OF saa5050_rom IS
+-
+- SIGNAL sub_wire0 : STD_LOGIC_VECTOR (7 DOWNTO 0);
+-
+-
+-
+- COMPONENT altsyncram
+- GENERIC (
+- clock_enable_input_a : STRING;
+- clock_enable_output_a : STRING;
+- init_file : STRING;
+- intended_device_family : STRING;
+- lpm_hint : STRING;
+- lpm_type : STRING;
+- numwords_a : NATURAL;
+- operation_mode : STRING;
+- outdata_aclr_a : STRING;
+- outdata_reg_a : STRING;
+- widthad_a : NATURAL;
+- width_a : NATURAL;
+- width_byteena_a : NATURAL
+- );
+- PORT (
+- clock0 : IN STD_LOGIC ;
+- address_a : IN STD_LOGIC_VECTOR (11 DOWNTO 0);
+- q_a : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
+- );
+- END COMPONENT;
+-
+-BEGIN
+- q <= sub_wire0(7 DOWNTO 0);
+-
+- altsyncram_component : altsyncram
+- GENERIC MAP (
+- clock_enable_input_a => "BYPASS",
+- clock_enable_output_a => "BYPASS",
+- init_file => "./roms/saa5050/saa5050.hex",
+- intended_device_family => "Cyclone II",
+- lpm_hint => "ENABLE_RUNTIME_MOD=NO",
+- lpm_type => "altsyncram",
+- numwords_a => 4096,
+- operation_mode => "ROM",
+- outdata_aclr_a => "NONE",
+- outdata_reg_a => "UNREGISTERED",
+- widthad_a => 12,
+- width_a => 8,
+- width_byteena_a => 1
+- )
+- PORT MAP (
+- clock0 => clock,
+- address_a => address,
+- q_a => sub_wire0
+- );
+-
+-
+-
+-END SYN;
+-
+--- ============================================================
+--- CNX file retrieval info
+--- ============================================================
+--- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
+--- Retrieval info: PRIVATE: AclrAddr NUMERIC "0"
+--- Retrieval info: PRIVATE: AclrByte NUMERIC "0"
+--- Retrieval info: PRIVATE: AclrOutput NUMERIC "0"
+--- Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0"
+--- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
+--- Retrieval info: PRIVATE: BlankMemory NUMERIC "0"
+--- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
+--- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
+--- Retrieval info: PRIVATE: Clken NUMERIC "0"
+--- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
+--- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
+--- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
+--- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
+--- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
+--- Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
+--- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
+--- Retrieval info: PRIVATE: MIFfilename STRING "./roms/saa5050/saa5050.hex"
+--- Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "4096"
+--- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
+--- Retrieval info: PRIVATE: RegAddr NUMERIC "1"
+--- Retrieval info: PRIVATE: RegOutput NUMERIC "0"
+--- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
+--- Retrieval info: PRIVATE: SingleClock NUMERIC "1"
+--- Retrieval info: PRIVATE: UseDQRAM NUMERIC "0"
+--- Retrieval info: PRIVATE: WidthAddr NUMERIC "12"
+--- Retrieval info: PRIVATE: WidthData NUMERIC "8"
+--- Retrieval info: PRIVATE: rden NUMERIC "0"
+--- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
+--- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
+--- Retrieval info: CONSTANT: INIT_FILE STRING "./roms/saa5050/saa5050.hex"
+--- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
+--- Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO"
+--- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
+--- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "4096"
+--- Retrieval info: CONSTANT: OPERATION_MODE STRING "ROM"
+--- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
+--- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED"
+--- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "12"
+--- Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
+--- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
+--- Retrieval info: USED_PORT: address 0 0 12 0 INPUT NODEFVAL address[11..0]
+--- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL clock
+--- Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL q[7..0]
+--- Retrieval info: CONNECT: @address_a 0 0 12 0 address 0 0 12 0
+--- Retrieval info: CONNECT: q 0 0 8 0 @q_a 0 0 8 0
+--- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
+--- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
+--- Retrieval info: GEN_FILE: TYPE_NORMAL saa5050_rom.vhd TRUE
+--- Retrieval info: GEN_FILE: TYPE_NORMAL saa5050_rom.inc FALSE
+--- Retrieval info: GEN_FILE: TYPE_NORMAL saa5050_rom.cmp FALSE
+--- Retrieval info: GEN_FILE: TYPE_NORMAL saa5050_rom.bsf FALSE
+--- Retrieval info: GEN_FILE: TYPE_NORMAL saa5050_rom_inst.vhd FALSE
+--- Retrieval info: GEN_FILE: TYPE_NORMAL saa5050_rom_waveforms.html FALSE
+--- Retrieval info: GEN_FILE: TYPE_NORMAL saa5050_rom_wave*.jpg FALSE
+--- Retrieval info: LIB_FILE: altera_mf
++-- megafunction wizard: %ROM: 1-PORT%
++-- GENERATION: STANDARD
++-- VERSION: WM1.0
++-- MODULE: altsyncram
++
++-- ============================================================
++-- File Name: saa5050_rom.vhd
++-- Megafunction Name(s):
++-- altsyncram
++--
++-- Simulation Library Files(s):
++-- altera_mf
++-- ============================================================
++-- ************************************************************
++-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
++--
++-- 9.1 Build 222 10/21/2009 SJ Web Edition
++-- ************************************************************
++
++
++--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.
++
++
++LIBRARY ieee;
++USE ieee.std_logic_1164.all;
++
++LIBRARY altera_mf;
++USE altera_mf.all;
++
++ENTITY saa5050_rom IS
++ PORT
++ (
++ address : IN STD_LOGIC_VECTOR (11 DOWNTO 0);
++ clock : IN STD_LOGIC ;
++ q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
++ );
++END saa5050_rom;
++
++
++ARCHITECTURE SYN OF saa5050_rom IS
++
++ SIGNAL sub_wire0 : STD_LOGIC_VECTOR (7 DOWNTO 0);
++
++
++
++ COMPONENT altsyncram
++ GENERIC (
++ clock_enable_input_a : STRING;
++ clock_enable_output_a : STRING;
++ init_file : STRING;
++ intended_device_family : STRING;
++ lpm_hint : STRING;
++ lpm_type : STRING;
++ numwords_a : NATURAL;
++ operation_mode : STRING;
++ outdata_aclr_a : STRING;
++ outdata_reg_a : STRING;
++ widthad_a : NATURAL;
++ width_a : NATURAL;
++ width_byteena_a : NATURAL
++ );
++ PORT (
++ clock0 : IN STD_LOGIC ;
++ address_a : IN STD_LOGIC_VECTOR (11 DOWNTO 0);
++ q_a : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
++ );
++ END COMPONENT;
++
++BEGIN
++ q <= sub_wire0(7 DOWNTO 0);
++
++ altsyncram_component : altsyncram
++ GENERIC MAP (
++ clock_enable_input_a => "BYPASS",
++ clock_enable_output_a => "BYPASS",
++ init_file => "./roms/saa5050/saa5050.hex",
++ intended_device_family => "Cyclone II",
++ lpm_hint => "ENABLE_RUNTIME_MOD=NO",
++ lpm_type => "altsyncram",
++ numwords_a => 4096,
++ operation_mode => "ROM",
++ outdata_aclr_a => "NONE",
++ outdata_reg_a => "UNREGISTERED",
++ widthad_a => 12,
++ width_a => 8,
++ width_byteena_a => 1
++ )
++ PORT MAP (
++ clock0 => clock,
++ address_a => address,
++ q_a => sub_wire0
++ );
++
++
++
++END SYN;
++
++-- ============================================================
++-- CNX file retrieval info
++-- ============================================================
++-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
++-- Retrieval info: PRIVATE: AclrAddr NUMERIC "0"
++-- Retrieval info: PRIVATE: AclrByte NUMERIC "0"
++-- Retrieval info: PRIVATE: AclrOutput NUMERIC "0"
++-- Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0"
++-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
++-- Retrieval info: PRIVATE: BlankMemory NUMERIC "0"
++-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
++-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
++-- Retrieval info: PRIVATE: Clken NUMERIC "0"
++-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
++-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
++-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
++-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
++-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
++-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
++-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
++-- Retrieval info: PRIVATE: MIFfilename STRING "./roms/saa5050/saa5050.hex"
++-- Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "4096"
++-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
++-- Retrieval info: PRIVATE: RegAddr NUMERIC "1"
++-- Retrieval info: PRIVATE: RegOutput NUMERIC "0"
++-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
++-- Retrieval info: PRIVATE: SingleClock NUMERIC "1"
++-- Retrieval info: PRIVATE: UseDQRAM NUMERIC "0"
++-- Retrieval info: PRIVATE: WidthAddr NUMERIC "12"
++-- Retrieval info: PRIVATE: WidthData NUMERIC "8"
++-- Retrieval info: PRIVATE: rden NUMERIC "0"
++-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
++-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
++-- Retrieval info: CONSTANT: INIT_FILE STRING "./roms/saa5050/saa5050.hex"
++-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
++-- Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO"
++-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
++-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "4096"
++-- Retrieval info: CONSTANT: OPERATION_MODE STRING "ROM"
++-- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
++-- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED"
++-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "12"
++-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
++-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
++-- Retrieval info: USED_PORT: address 0 0 12 0 INPUT NODEFVAL address[11..0]
++-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL clock
++-- Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL q[7..0]
++-- Retrieval info: CONNECT: @address_a 0 0 12 0 address 0 0 12 0
++-- Retrieval info: CONNECT: q 0 0 8 0 @q_a 0 0 8 0
++-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
++-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
++-- Retrieval info: GEN_FILE: TYPE_NORMAL saa5050_rom.vhd TRUE
++-- Retrieval info: GEN_FILE: TYPE_NORMAL saa5050_rom.inc FALSE
++-- Retrieval info: GEN_FILE: TYPE_NORMAL saa5050_rom.cmp FALSE
++-- Retrieval info: GEN_FILE: TYPE_NORMAL saa5050_rom.bsf FALSE
++-- Retrieval info: GEN_FILE: TYPE_NORMAL saa5050_rom_inst.vhd FALSE
++-- Retrieval info: GEN_FILE: TYPE_NORMAL saa5050_rom_waveforms.html FALSE
++-- Retrieval info: GEN_FILE: TYPE_NORMAL saa5050_rom_wave*.jpg FALSE
++-- Retrieval info: LIB_FILE: altera_mf
+diff --git a/seg7.vhd b/seg7.vhd
+index a61e679..566b1f6 100644
+--- a/seg7.vhd
++++ b/seg7.vhd
+@@ -1,68 +1,68 @@
+--- BBC Micro for Altera DE1
+---
+--- Copyright (c) 2009-2011 Mike Stirling
+---
+--- 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 agreement from the author.
+---
+--- * License is granted for non-commercial use only. A fee may not be charged
+--- for redistributions as source code or in synthesized/hardware form without
+--- specific prior written agreement from the author.
+---
+--- 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.
+---
+-
+-library ieee;
+-use ieee.std_logic_1164.all;
+-
+--- Convert BCD to 7-segment display characters
+-entity seg7 is
+-port (
+- D : in std_logic_vector(3 downto 0);
+- Q : out std_logic_vector(6 downto 0)
+-);
+-end seg7;
+-
+-architecture seg7_arch of seg7 is
+-begin
+- Q <= "1000000" when D = "0000" else
+- "1111001" when D = "0001" else
+- "0100100" when D = "0010" else
+- "0110000" when D = "0011" else
+- "0011001" when D = "0100" else
+- "0010010" when D = "0101" else
+- "0000010" when D = "0110" else
+- "1111000" when D = "0111" else
+- "0000000" when D = "1000" else
+- "0010000" when D = "1001" else
+- "0001000" when D = "1010" else
+- "0000011" when D = "1011" else
+- "1000110" when D = "1100" else
+- "0100001" when D = "1101" else
+- "0000110" when D = "1110" else
+- "0001110";
+-end seg7_arch;
+-
++-- BBC Micro for Altera DE1
++--
++-- Copyright (c) 2009-2011 Mike Stirling
++--
++-- 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 agreement from the author.
++--
++-- * License is granted for non-commercial use only. A fee may not be charged
++-- for redistributions as source code or in synthesized/hardware form without
++-- specific prior written agreement from the author.
++--
++-- 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.
++--
++
++library ieee;
++use ieee.std_logic_1164.all;
++
++-- Convert BCD to 7-segment display characters
++entity seg7 is
++port (
++ D : in std_logic_vector(3 downto 0);
++ Q : out std_logic_vector(6 downto 0)
++);
++end seg7;
++
++architecture seg7_arch of seg7 is
++begin
++ Q <= "1000000" when D = "0000" else
++ "1111001" when D = "0001" else
++ "0100100" when D = "0010" else
++ "0110000" when D = "0011" else
++ "0011001" when D = "0100" else
++ "0010010" when D = "0101" else
++ "0000010" when D = "0110" else
++ "1111000" when D = "0111" else
++ "0000000" when D = "1000" else
++ "0010000" when D = "1001" else
++ "0001000" when D = "1010" else
++ "0000011" when D = "1011" else
++ "1000110" when D = "1100" else
++ "0100001" when D = "1101" else
++ "0000110" when D = "1110" else
++ "0001110";
++end seg7_arch;
++
+diff --git a/sn76489-1.0/sn76489_top.vhd b/sn76489-1.0/sn76489_top.vhd
+index 277f601..deb8170 100644
+--- a/sn76489-1.0/sn76489_top.vhd
++++ b/sn76489-1.0/sn76489_top.vhd
+@@ -196,15 +196,15 @@ begin
+ noise_o => noise_s
+ );
+
+-
++
+ -- Register output
+- process(clock_i)
+- begin
+- if res_n_i = '0' then
+- aout_o <= (others => '0');
+- elsif rising_edge(clock_i) then
+- aout_o <= tone1_s + tone2_s + tone3_s + noise_s;
+- end if;
+- end process;
++ process(clock_i)
++ begin
++ if res_n_i = '0' then
++ aout_o <= (others => '0');
++ elsif rising_edge(clock_i) then
++ aout_o <= tone1_s + tone2_s + tone3_s + noise_s;
++ end if;
++ end process;
+
+ end struct;
+diff --git a/vidproc.vhd b/vidproc.vhd
+index 6d5f91f..25f3d75 100644
+--- a/vidproc.vhd
++++ b/vidproc.vhd
+@@ -1,279 +1,279 @@
+--- BBC Micro for Altera DE1
+---
+--- Copyright (c) 2011 Mike Stirling
+---
+--- 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 agreement from the author.
+---
+--- * License is granted for non-commercial use only. A fee may not be charged
+--- for redistributions as source code or in synthesized/hardware form without
+--- specific prior written agreement from the author.
+---
+--- 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.
+---
+--- 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_fetch : std_logic;
+-signal clken_counter : unsigned(3 downto 0);
+-
+--- Cursor generation - can span up to 32 pixels
+--- Segments 0 and 1 are 8 pixels wide
+--- Segment 2 is 16 pixels wide
+-signal cursor_invert : std_logic;
+-signal cursor_active : std_logic;
+-signal cursor_counter : unsigned(1 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);
+- -- The result is fetched from the CRTC in cycle 0 and also cycle 8 if 2 MHz
+- -- mode is selected. This is used for reloading the shift register as well as
+- -- counting cursor pixels
+- clken_fetch <= CLKEN and not (clken_counter(0) or clken_counter(1) or clken_counter(2) or
+- (clken_counter(3) and not 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_fetch = '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;
+-
+- -- Cursor generation
+- cursor_invert <= cursor_active and
+- ((r0_cursor0 and not (cursor_counter(0) or cursor_counter(1))) or
+- (r0_cursor1 and cursor_counter(0) and not cursor_counter(1)) or
+- (r0_cursor2 and cursor_counter(1)));
+- process(CLOCK,nRESET)
+- begin
+- if nRESET = '0' then
+- cursor_active <= '0';
+- cursor_counter <= (others => '0');
+- elsif rising_edge(CLOCK) and clken_fetch = '1' then
+- if CURSOR = '1' or cursor_active = '1' then
+- -- Latch cursor
+- cursor_active <= '1';
+-
+- -- Reset on counter wrap
+- if cursor_counter = "11" then
+- cursor_active <= '0';
+- end if;
+-
+- -- Increment counter
+- if cursor_active = '0' then
+- -- Reset
+- cursor_counter <= (others => '0');
+- else
+- -- Increment
+- cursor_counter <= cursor_counter + 1;
+- end if;
+- 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: INVERT option
+- if r0_teletext = '0' then
+- -- Cursor can extend outside the bounds of the screen, so
+- -- it is not affected by DISEN
+- R <= (red_val and delayed_disen) xor cursor_invert;
+- G <= (green_val and delayed_disen) xor cursor_invert;
+- B <= (blue_val and delayed_disen) xor cursor_invert;
+- else
+- R <= R_IN xor cursor_invert;
+- G <= G_IN xor cursor_invert;
+- B <= B_IN xor cursor_invert;
+- end if;
+-
+- -- Display enable signal delayed by one clock
+- delayed_disen <= DISEN;
+- end if;
+- end process;
+-end architecture;
+-
++-- BBC Micro for Altera DE1
++--
++-- Copyright (c) 2011 Mike Stirling
++--
++-- 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 agreement from the author.
++--
++-- * License is granted for non-commercial use only. A fee may not be charged
++-- for redistributions as source code or in synthesized/hardware form without
++-- specific prior written agreement from the author.
++--
++-- 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.
++--
++-- 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_fetch : std_logic;
++signal clken_counter : unsigned(3 downto 0);
++
++-- Cursor generation - can span up to 32 pixels
++-- Segments 0 and 1 are 8 pixels wide
++-- Segment 2 is 16 pixels wide
++signal cursor_invert : std_logic;
++signal cursor_active : std_logic;
++signal cursor_counter : unsigned(1 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);
++ -- The result is fetched from the CRTC in cycle 0 and also cycle 8 if 2 MHz
++ -- mode is selected. This is used for reloading the shift register as well as
++ -- counting cursor pixels
++ clken_fetch <= CLKEN and not (clken_counter(0) or clken_counter(1) or clken_counter(2) or
++ (clken_counter(3) and not 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_fetch = '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;
++
++ -- Cursor generation
++ cursor_invert <= cursor_active and
++ ((r0_cursor0 and not (cursor_counter(0) or cursor_counter(1))) or
++ (r0_cursor1 and cursor_counter(0) and not cursor_counter(1)) or
++ (r0_cursor2 and cursor_counter(1)));
++ process(CLOCK,nRESET)
++ begin
++ if nRESET = '0' then
++ cursor_active <= '0';
++ cursor_counter <= (others => '0');
++ elsif rising_edge(CLOCK) and clken_fetch = '1' then
++ if CURSOR = '1' or cursor_active = '1' then
++ -- Latch cursor
++ cursor_active <= '1';
++
++ -- Reset on counter wrap
++ if cursor_counter = "11" then
++ cursor_active <= '0';
++ end if;
++
++ -- Increment counter
++ if cursor_active = '0' then
++ -- Reset
++ cursor_counter <= (others => '0');
++ else
++ -- Increment
++ cursor_counter <= cursor_counter + 1;
++ end if;
++ 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: INVERT option
++ if r0_teletext = '0' then
++ -- Cursor can extend outside the bounds of the screen, so
++ -- it is not affected by DISEN
++ R <= (red_val and delayed_disen) xor cursor_invert;
++ G <= (green_val and delayed_disen) xor cursor_invert;
++ B <= (blue_val and delayed_disen) xor cursor_invert;
++ else
++ R <= R_IN xor cursor_invert;
++ G <= G_IN xor cursor_invert;
++ B <= B_IN xor cursor_invert;
++ end if;
++
++ -- Display enable signal delayed by one clock
++ delayed_disen <= DISEN;
++ end if;
++ end process;
++end architecture;
++