Merge branch '38-increase-cpu-speed' into 'master'

Resolve "Increase CPU Speed"

Closes #38

See merge request bslathi19/super6502!33
This commit is contained in:
Byron Lathi
2023-10-16 01:45:44 +00:00
13 changed files with 392 additions and 145 deletions

View File

@@ -4,7 +4,7 @@ module sim_top();
`include "include/super6502_sdram_controller_define.vh"
logic r_sysclk, r_sdrclk, r_clk_50, r_clk_2;
logic r_sysclk, r_sdrclk, r_clk_50, r_clk_cpu;
// clk_100
initial begin
@@ -30,14 +30,18 @@ initial begin
end
end
// clk_2
// clk_cpu
initial begin
r_clk_2 <= '1;
r_clk_cpu <= '1;
forever begin
#250 r_clk_2 <= ~r_clk_2;
#125 r_clk_cpu <= ~r_clk_cpu;
end
end
// initial begin
// #275000 $finish();
// end
initial begin
$dumpfile("sim_top.vcd");
$dumpvars(0,sim_top);
@@ -47,9 +51,9 @@ logic button_reset;
initial begin
button_reset <= '0;
repeat(10) @(r_clk_2);
repeat(10) @(r_clk_cpu);
button_reset <= '1;
repeat(1000000) @(r_clk_2);
repeat(1000000) @(r_clk_cpu);
$finish();
end
@@ -101,7 +105,7 @@ super6502 u_dut(
.i_sdrclk(r_sdrclk),
.i_tACclk(~r_sdrclk),
.clk_50(r_clk_50),
.clk_2(r_clk_2),
.clk_cpu(r_clk_cpu),
.button_reset(button_reset),
.cpu_resb(w_cpu_reset),
.cpu_addr(w_cpu_addr),

View File

@@ -70,10 +70,11 @@ assign o_sdr_DQM = w_sdr_DQM[0+:2];
// But basically if we are in access, and cpuclk goes low, go back to wait.
// If something actually happened, we would be in one of the read/write states.
enum bit [1:0] {ACCESS, READ_WAIT, WRITE_WAIT, WAIT} state, next_state;
enum bit [2:0] {ACCESS, PRE_READ, READ_WAIT, PRE_WRITE, WRITE_WAIT, WAIT} state, next_state;
logic w_read, w_write, w_last;
logic [23:0] w_addr, r_addr;
logic [23:0] w_read_addr, w_write_addr;
logic [23:0] r_read_addr, r_write_addr;
logic [31:0] w_data_i, w_data_o;
logic [3:0] w_dm, r_dm;
@@ -86,25 +87,15 @@ logic [31:0] r_write_data;
logic [1:0] counter, next_counter;
always @(posedge i_sysclk) begin
if (i_arst) begin
state <= WAIT;
counter <= '0;
end else begin
state <= next_state;
counter <= next_counter;
r_write_data <= w_data_i;
r_addr <= w_addr;
r_dm <= w_dm;
end
if (w_data_valid)
o_data <= _data;
end
logic [7:0] o_data_next;
logic [23:0] addr_mux_out;
logic slow_mem;
logic r_wait;
logic _r_wait;
assign o_wait = r_wait & i_cs;
assign o_wait = (r_wait | slow_mem) & i_cs;
// we need to assert rdy low until a falling edge if a reset happens
@@ -126,6 +117,20 @@ always @(posedge i_sysclk or posedge i_arst) begin
end
end
end
if (i_arst) begin
state <= WAIT;
counter <= '0;
end else begin
state <= next_state;
counter <= next_counter;
r_write_data <= w_data_i;
r_read_addr <= w_read_addr;
r_write_addr <= w_write_addr;
r_dm <= w_dm;
end
o_data <= o_data_next;
end
//because of timing issues, We really need to trigger
@@ -157,10 +162,12 @@ end
always_comb begin
slow_mem = '0;
next_state = state;
next_counter = counter;
w_addr = '0;
w_read_addr = '0;
w_write_addr = '0;
w_dm = '0;
w_read = '0;
w_write = '0;
@@ -171,65 +178,81 @@ always_comb begin
unique case (state)
WAIT: begin
if (i_cs & i_cpuclk)
if (i_cs & ~i_cpuclk)
next_state = ACCESS;
end
ACCESS: begin
// only do something if selected
if (i_cs) begin
w_addr = {{i_addr[24:2]}, {1'b0}};; // divide by 2, set last bit to 0
w_read_addr = {{i_addr[24:2]}, {1'b0}}; // divide by 2, set last bit to 0
w_write_addr = {{i_addr[24:2]}, {1'b0}}; // divide by 2, set last bit to 0
addr_mux_out = w_read_addr;
if (i_rwb) begin //read
w_read = '1;
w_last = '1;
// dm is not needed for reads?
if (w_rd_ack) next_state = READ_WAIT;
next_state = PRE_READ;
end else begin //write
w_data_i = i_data << (8*i_addr[1:0]);
//w_data_i = {4{i_data}}; //does anything get through?
w_dm = ~(4'b1 << i_addr[1:0]);
if (~i_cpuclk) begin
w_write = '1;
w_last = '1;
next_state = WRITE_WAIT;
end
next_state = PRE_WRITE;
end
end
end
PRE_WRITE: begin
w_data_i = r_write_data;
w_write_addr = r_write_addr;
addr_mux_out = w_write_addr;
w_dm = r_dm;
//w_data_i = {4{i_data}}; //does anything get through?
if (~i_cpuclk) begin
w_write = '1;
w_last = '1;
next_state = WRITE_WAIT;
end
end
WRITE_WAIT: begin
// stay in this state until write is acknowledged.
w_write_addr = r_write_addr;
addr_mux_out = w_write_addr;
w_write = '1;
w_last = '1;
w_data_i = r_write_data;
w_dm = r_dm;
w_addr = r_addr;
if (w_wr_ack) next_state = WAIT;
end
PRE_READ: begin
w_read_addr = r_read_addr;
addr_mux_out = w_read_addr;
w_read = '1;
w_last = '1;
slow_mem = '1;
// dm is not needed for reads?
if (w_rd_ack) next_state = READ_WAIT;
end
READ_WAIT: begin
w_read_addr = r_read_addr;
addr_mux_out = w_read_addr;
slow_mem = '1;
if (w_rd_valid) begin
w_data_valid = '1;
_data = w_data_o[8*i_addr[1:0]+:8];
end
// you must wait until the next cycle!
if (~i_cpuclk) begin
if (w_data_valid) begin
next_state = WAIT;
end
end
endcase
end
//this seems scuffed
logic [23:0] addr_mux_out;
always_comb begin
if (state == ACCESS) begin
addr_mux_out = w_addr;
if (w_data_valid) begin
o_data_next = _data;
end else begin
addr_mux_out = r_addr;
o_data_next = o_data;
end
end

View File

@@ -11,7 +11,7 @@ module super6502
input button_reset,
input pll_cpu_locked,
input clk_50,
input clk_2,
input clk_cpu,
input logic [15:0] cpu_addr,
output logic [7:0] cpu_data_out,
output logic [7:0] cpu_data_oe,
@@ -56,11 +56,11 @@ assign cpu_nmib = '1;
logic w_wait;
assign cpu_rdy = ~w_wait;
assign cpu_phi2 = clk_2;
assign cpu_phi2 = clk_cpu;
logic w_sdr_init_done;
always @(posedge clk_2) begin
always @(posedge clk_cpu) begin
if (button_reset == '0) begin
cpu_resb <= '0;
end
@@ -124,12 +124,12 @@ end
rom #(.DATA_WIDTH(8), .ADDR_WIDTH(12)) u_rom(
.addr(cpu_addr[11:0]),
.clk(clk_2),
.clk(clk_cpu),
.data(w_rom_data_out)
);
leds u_leds(
.clk(clk_2),
.clk(clk_cpu),
.i_data(cpu_data_in),
.o_data(w_leds_data_out),
.cs(w_leds_cs),
@@ -140,7 +140,7 @@ leds u_leds(
logic w_timer_irqb;
timer u_timer(
.clk(clk_2),
.clk(clk_cpu),
.reset(~cpu_resb),
.i_data(cpu_data_in),
.o_data(w_timer_data_out),
@@ -151,7 +151,7 @@ timer u_timer(
);
multiplier u_multiplier(
.clk(clk_2),
.clk(clk_cpu),
.reset(~cpu_resb),
.i_data(cpu_data_in),
.o_data(w_multiplier_data_out),
@@ -161,7 +161,7 @@ multiplier u_multiplier(
);
divider_wrapper u_divider(
.clk(clk_2),
.clk(clk_cpu),
.divclk(clk_50),
.reset(~cpu_resb),
.i_data(cpu_data_in),
@@ -174,7 +174,7 @@ divider_wrapper u_divider(
logic w_uart_irqb;
uart_wrapper u_uart(
.clk(clk_2),
.clk(clk_cpu),
.clk_50(clk_50),
.reset(~cpu_resb),
.i_data(cpu_data_in),
@@ -188,7 +188,7 @@ uart_wrapper u_uart(
);
spi_controller spi_controller(
.i_clk(clk_2),
.i_clk(clk_cpu),
.i_rst(~cpu_resb),
.i_cs(w_spi_cs),
.i_rwb(cpu_rwb),
@@ -204,7 +204,7 @@ spi_controller spi_controller(
sdram_adapter u_sdram_adapter(
.i_cpuclk(clk_2),
.i_cpuclk(clk_cpu),
.i_arst(~button_reset),
.i_sysclk(i_sysclk),
.i_sdrclk(i_sdrclk),
@@ -234,7 +234,7 @@ sdram_adapter u_sdram_adapter(
);
interrupt_controller u_interrupt_controller(
.clk(clk_2),
.clk(clk_cpu),
.reset(~cpu_resb),
.i_data(cpu_data_in),
.o_data(w_irq_data_out),

View File

@@ -1,105 +1,106 @@
<efx:project xmlns:efx="http://www.efinixinc.com/enf_proj" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="super6502" description="" last_change_date="Thu Sep 28 2023 09:38:33 PM" location="/home/byron/ServerProjects/super6502/hw/efinix_fpga" sw_version="2023.1.150" last_run_state="pass" last_run_tool="efx_pgm" last_run_flow="bitstream" config_result_in_sync="sync" design_ood="sync" place_ood="sync" route_ood="sync" xsi:schemaLocation="http://www.efinixinc.com/enf_proj enf_proj.xsd">
<?xml version="1.0" encoding="UTF-8"?>
<efx:project name="super6502" description="" last_change_date="Sun October 15 2023 13:52:14" location="/home/byron/ServerProjects/super6502/hw/efinix_fpga" sw_version="2022.2.322" last_run_state="pass" last_run_tool="efx_pgm" last_run_flow="bitstream" config_result_in_sync="sync" design_ood="sync" place_ood="sync" route_ood="sync" xmlns:efx="http://www.efinixinc.com/enf_proj" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.efinixinc.com/enf_proj enf_proj.xsd">
<efx:device_info>
<efx:family name="Trion" />
<efx:device name="T20F256" />
<efx:timing_model name="C4" />
<efx:family name="Trion"/>
<efx:device name="T20F256"/>
<efx:timing_model name="C4"/>
</efx:device_info>
<efx:design_info def_veri_version="sv_09" def_vhdl_version="vhdl_2008">
<efx:top_module name="super6502" />
<efx:design_file name="src/super6502.sv" version="default" library="default" />
<efx:design_file name="src/leds.sv" version="default" library="default" />
<efx:design_file name="src/addr_decode.sv" version="default" library="default" />
<efx:design_file name="src/sdram_adapter.sv" version="default" library="default" />
<efx:design_file name="src/timer.sv" version="default" library="default" />
<efx:design_file name="src/interrupt_controller.sv" version="default" library="default" />
<efx:design_file name="src/multiplier.sv" version="default" library="default" />
<efx:design_file name="src/divider_wrapper.sv" version="default" library="default" />
<efx:design_file name="src/uart_wrapper.sv" version="default" library="default" />
<efx:design_file name="src/sd_controller.sv" version="default" library="default" />
<efx:design_file name="src/crc7.sv" version="default" library="default" />
<efx:design_file name="src/rom.sv" version="default" library="default" />
<efx:design_file name="src/spi_controller.sv" version="default" library="default" />
<efx:top_vhdl_arch name="" />
<efx:top_module name="super6502"/>
<efx:design_file name="src/super6502.sv" version="default" library="default"/>
<efx:design_file name="src/leds.sv" version="default" library="default"/>
<efx:design_file name="src/addr_decode.sv" version="default" library="default"/>
<efx:design_file name="src/sdram_adapter.sv" version="default" library="default"/>
<efx:design_file name="src/timer.sv" version="default" library="default"/>
<efx:design_file name="src/interrupt_controller.sv" version="default" library="default"/>
<efx:design_file name="src/multiplier.sv" version="default" library="default"/>
<efx:design_file name="src/divider_wrapper.sv" version="default" library="default"/>
<efx:design_file name="src/uart_wrapper.sv" version="default" library="default"/>
<efx:design_file name="src/sd_controller.sv" version="default" library="default"/>
<efx:design_file name="src/crc7.sv" version="default" library="default"/>
<efx:design_file name="src/rom.sv" version="default" library="default"/>
<efx:design_file name="src/spi_controller.sv" version="default" library="default"/>
<efx:top_vhdl_arch name=""/>
</efx:design_info>
<efx:constraint_info>
<efx:sdc_file name="constraints/super6502.pt.sdc" />
<efx:inter_file name="" />
<efx:sdc_file name="constraints/super6502.pt.sdc"/>
<efx:inter_file name=""/>
</efx:constraint_info>
<efx:sim_info />
<efx:misc_info />
<efx:sim_info/>
<efx:misc_info/>
<efx:ip_info>
<efx:ip instance_name="sdram_controller" path="ip/sdram_controller/settings.json">
<efx:ip_src_file name="sdram_controller.v" />
<efx:ip_src_file name="sdram_controller.v"/>
</efx:ip>
<efx:ip instance_name="divider" path="ip/divider/settings.json">
<efx:ip_src_file name="divider.v" />
<efx:ip_src_file name="divider.v"/>
</efx:ip>
<efx:ip instance_name="uart" path="ip/uart/settings.json">
<efx:ip_src_file name="uart.v" />
<efx:ip_src_file name="uart.v"/>
</efx:ip>
</efx:ip_info>
<efx:synthesis tool_name="efx_map">
<efx:param name="work_dir" value="work_syn" value_type="e_string" />
<efx:param name="write_efx_verilog" value="on" value_type="e_bool" />
<efx:param name="mode" value="speed" value_type="e_option" />
<efx:param name="max_ram" value="-1" value_type="e_integer" />
<efx:param name="max_mult" value="-1" value_type="e_integer" />
<efx:param name="infer-clk-enable" value="3" value_type="e_option" />
<efx:param name="infer-sync-set-reset" value="1" value_type="e_option" />
<efx:param name="fanout-limit" value="0" value_type="e_integer" />
<efx:param name="bram_output_regs_packing" value="1" value_type="e_option" />
<efx:param name="retiming" value="1" value_type="e_option" />
<efx:param name="seq_opt" value="1" value_type="e_option" />
<efx:param name="blast_const_operand_adders" value="1" value_type="e_option" />
<efx:param name="operator-sharing" value="0" value_type="e_option" />
<efx:param name="optimize-adder-tree" value="0" value_type="e_option" />
<efx:param name="mult_input_regs_packing" value="1" value_type="e_option" />
<efx:param name="mult_output_regs_packing" value="1" value_type="e_option" />
<efx:param name="min-sr-fanout" value="0" value_type="e_option" />
<efx:param name="seq-opt-sync-only" value="0" value_type="e_option" />
<efx:param name="blackbox-error" value="1" value_type="e_option" />
<efx:param name="allow-const-ram-index" value="0" value_type="e_option" />
<efx:param name="hdl-compile-unit" value="1" value_type="e_option" />
<efx:param name="create-onehot-fsms" value="0" value_type="e_option" />
<efx:param name="min-ce-fanout" value="0" value_type="e_integer" />
<efx:param name="mult-decomp-retime" value="0" value_type="e_option" />
<efx:param name="optimize-zero-init-rom" value="1" value_type="e_option" />
<efx:param name="include" value="ip/sdram_controller" value_type="e_string" />
<efx:param name="include" value="ip/divider" value_type="e_string" />
<efx:param name="include" value="ip/uart" value_type="e_string" />
<efx:param name="work_dir" value="work_syn" value_type="e_string"/>
<efx:param name="write_efx_verilog" value="on" value_type="e_bool"/>
<efx:param name="mode" value="speed" value_type="e_option"/>
<efx:param name="max_ram" value="-1" value_type="e_integer"/>
<efx:param name="max_mult" value="-1" value_type="e_integer"/>
<efx:param name="infer-clk-enable" value="3" value_type="e_option"/>
<efx:param name="infer-sync-set-reset" value="1" value_type="e_option"/>
<efx:param name="fanout-limit" value="0" value_type="e_integer"/>
<efx:param name="bram_output_regs_packing" value="1" value_type="e_option"/>
<efx:param name="retiming" value="1" value_type="e_option"/>
<efx:param name="seq_opt" value="1" value_type="e_option"/>
<efx:param name="blast_const_operand_adders" value="1" value_type="e_option"/>
<efx:param name="operator-sharing" value="0" value_type="e_option"/>
<efx:param name="optimize-adder-tree" value="0" value_type="e_option"/>
<efx:param name="mult_input_regs_packing" value="1" value_type="e_option"/>
<efx:param name="mult_output_regs_packing" value="1" value_type="e_option"/>
<efx:param name="min-sr-fanout" value="0" value_type="e_option"/>
<efx:param name="seq-opt-sync-only" value="0" value_type="e_option"/>
<efx:param name="blackbox-error" value="1" value_type="e_option"/>
<efx:param name="allow-const-ram-index" value="0" value_type="e_option"/>
<efx:param name="hdl-compile-unit" value="1" value_type="e_option"/>
<efx:param name="create-onehot-fsms" value="0" value_type="e_option"/>
<efx:param name="min-ce-fanout" value="0" value_type="e_integer"/>
<efx:param name="mult-decomp-retime" value="0" value_type="e_option"/>
<efx:param name="optimize-zero-init-rom" value="1" value_type="e_option"/>
<efx:param name="include" value="ip/sdram_controller" value_type="e_string"/>
<efx:param name="include" value="ip/divider" value_type="e_string"/>
<efx:param name="include" value="ip/uart" value_type="e_string"/>
</efx:synthesis>
<efx:place_and_route tool_name="efx_pnr">
<efx:param name="work_dir" value="work_pnr" value_type="e_string" />
<efx:param name="verbose" value="off" value_type="e_bool" />
<efx:param name="load_delaym" value="on" value_type="e_bool" />
<efx:param name="optimization_level" value="NULL" value_type="e_option" />
<efx:param name="seed" value="1" value_type="e_integer" />
<efx:param name="placer_effort_level" value="2" value_type="e_option" />
<efx:param name="max_threads" value="-1" value_type="e_integer" />
<efx:param name="work_dir" value="work_pnr" value_type="e_string"/>
<efx:param name="verbose" value="off" value_type="e_bool"/>
<efx:param name="load_delaym" value="on" value_type="e_bool"/>
<efx:param name="optimization_level" value="NULL" value_type="e_option"/>
<efx:param name="seed" value="1" value_type="e_integer"/>
<efx:param name="placer_effort_level" value="2" value_type="e_option"/>
<efx:param name="max_threads" value="-1" value_type="e_integer"/>
</efx:place_and_route>
<efx:bitstream_generation tool_name="efx_pgm">
<efx:param name="mode" value="active" value_type="e_option" />
<efx:param name="width" value="1" value_type="e_option" />
<efx:param name="enable_roms" value="smart" value_type="e_option" />
<efx:param name="spi_low_power_mode" value="on" value_type="e_bool" />
<efx:param name="io_weak_pullup" value="on" value_type="e_bool" />
<efx:param name="oscillator_clock_divider" value="DIV8" value_type="e_option" />
<efx:param name="bitstream_compression" value="off" value_type="e_bool" />
<efx:param name="enable_external_master_clock" value="off" value_type="e_bool" />
<efx:param name="active_capture_clk_edge" value="posedge" value_type="e_option" />
<efx:param name="jtag_usercode" value="0xFFFFFFFF" value_type="e_string" />
<efx:param name="release_tri_then_reset" value="on" value_type="e_bool" />
<efx:param name="cold_boot" value="off" value_type="e_bool" />
<efx:param name="cascade" value="off" value_type="e_option" />
<efx:param name="generate_bit" value="on" value_type="e_bool" />
<efx:param name="generate_bitbin" value="off" value_type="e_bool" />
<efx:param name="generate_hex" value="on" value_type="e_bool" />
<efx:param name="generate_hexbin" value="off" value_type="e_bool" />
<efx:param name="four_byte_addressing" value="off" value_type="e_bool" />
<efx:param name="mode" value="active" value_type="e_option"/>
<efx:param name="width" value="1" value_type="e_option"/>
<efx:param name="enable_roms" value="smart" value_type="e_option"/>
<efx:param name="spi_low_power_mode" value="on" value_type="e_bool"/>
<efx:param name="io_weak_pullup" value="on" value_type="e_bool"/>
<efx:param name="oscillator_clock_divider" value="DIV8" value_type="e_option"/>
<efx:param name="bitstream_compression" value="off" value_type="e_bool"/>
<efx:param name="enable_external_master_clock" value="off" value_type="e_bool"/>
<efx:param name="active_capture_clk_edge" value="posedge" value_type="e_option"/>
<efx:param name="jtag_usercode" value="0xFFFFFFFF" value_type="e_string"/>
<efx:param name="release_tri_then_reset" value="on" value_type="e_bool"/>
<efx:param name="cold_boot" value="off" value_type="e_bool"/>
<efx:param name="cascade" value="off" value_type="e_option"/>
<efx:param name="generate_bit" value="on" value_type="e_bool"/>
<efx:param name="generate_bitbin" value="off" value_type="e_bool"/>
<efx:param name="generate_hex" value="on" value_type="e_bool"/>
<efx:param name="generate_hexbin" value="off" value_type="e_bool"/>
<efx:param name="four_byte_addressing" value="off" value_type="e_bool"/>
</efx:bitstream_generation>
<efx:debugger>
<efx:param name="work_dir" value="work_dbg" value_type="e_string" />
<efx:param name="auto_instantiation" value="off" value_type="e_bool" />
<efx:param name="profile" value="debug_profile.wizard.json" value_type="e_string" />
<efx:param name="work_dir" value="work_dbg" value_type="e_string"/>
<efx:param name="auto_instantiation" value="off" value_type="e_bool"/>
<efx:param name="profile" value="debug_profile.wizard.json" value_type="e_string"/>
</efx:debugger>
</efx:project>
</efx:project>

View File

@@ -17,6 +17,6 @@ kernel:
clean:
@$(MAKE) -C bootloader --no-print-directory $@
@$(MAKE) -C bios --no-print-directory $@
@$(MAKE) -C kernel --no-print-directory $@
@$(MAKE) -C cc65 --no-print-directory $@
@$(MAKE) -C cc65 --no-print-directory $@

View File

@@ -0,0 +1,39 @@
CC=../../cc65/bin/cl65
LD=../../cc65/bin/cl65
CFLAGS=-T -t none -I. --cpu "65C02"
LDFLAGS=-C link.ld -m $(NAME).map
NAME=indirect_test
BIN=$(NAME).bin
HEX=$(NAME).hex
LISTS=lists
SRCS=$(wildcard *.s) $(wildcard *.c)
SRCS+=$(wildcard **/*.s) $(wildcard **/*.c)
OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS)))
OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS)))
# Make sure the kernel linked to correct address, no relocation!
all: $(HEX)
$(HEX): $(BIN)
objcopy --input-target=binary --output-target=verilog $(BIN) $(HEX)
$(BIN): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@
%.o: %.c $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
%.o: %.s $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
$(LISTS):
mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS))))
.PHONY: clean
clean:
rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map

View File

@@ -0,0 +1,35 @@
MEMORY
{
ZP: start = $0, size = $100, type = rw, define = yes;
SDRAM: start = $9200, size = $4d00, type = rw, define = yes;
ROM: start = $F000, size = $1000, file = %O;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp, define = yes;
DATA: load = ROM, type = rw, define = yes, run = SDRAM;
BSS: load = SDRAM, type = bss, define = yes;
HEAP: load = SDRAM, type = bss, optional = yes;
STARTUP: load = ROM, type = ro;
ONCE: load = ROM, type = ro, optional = yes;
CODE: load = ROM, type = ro;
RODATA: load = ROM, type = ro;
VECTORS: load = ROM, type = ro, start = $FFFA;
}
FEATURES {
CONDES: segment = STARTUP,
type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__;
CONDES: segment = STARTUP,
type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__;
}
SYMBOLS {
# Define the stack size for the application
__STACKSIZE__: value = $0200, type = weak;
__STACKSTART__: type = weak, value = $0800; # 2k stack
}

View File

@@ -0,0 +1,20 @@
.export _init, _nmi_int, _irq_int
.code
_nmi_int:
_irq_int:
_init:
ldx #$ff
txs
lda #$aa
sta $01
lda #$bb
sta $00
ldy #$1
lda #$cc
sta ($00),y
@end: bra @end

View File

@@ -0,0 +1,14 @@
; ---------------------------------------------------------------------------
; vectors.s
; ---------------------------------------------------------------------------
;
; Defines the interrupt vector table.
.import _init
.import _nmi_int, _irq_int
.segment "VECTORS"
.addr _nmi_int ; NMI vector
.addr _init ; Reset vector
.addr _irq_int ; IRQ/BRK vector

View File

@@ -0,0 +1,39 @@
CC=../../cc65/bin/cl65
LD=../../cc65/bin/cl65
CFLAGS=-T -t none -I. --cpu "65C02"
LDFLAGS=-C link.ld -m $(NAME).map
NAME=jsr_test
BIN=$(NAME).bin
HEX=$(NAME).hex
LISTS=lists
SRCS=$(wildcard *.s) $(wildcard *.c)
SRCS+=$(wildcard **/*.s) $(wildcard **/*.c)
OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS)))
OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS)))
# Make sure the kernel linked to correct address, no relocation!
all: $(HEX)
$(HEX): $(BIN)
objcopy --input-target=binary --output-target=verilog $(BIN) $(HEX)
$(BIN): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@
%.o: %.c $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
%.o: %.s $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
$(LISTS):
mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS))))
.PHONY: clean
clean:
rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map

View File

@@ -0,0 +1,35 @@
MEMORY
{
ZP: start = $0, size = $100, type = rw, define = yes;
SDRAM: start = $9200, size = $4d00, type = rw, define = yes;
ROM: start = $F000, size = $1000, file = %O;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp, define = yes;
DATA: load = ROM, type = rw, define = yes, run = SDRAM;
BSS: load = SDRAM, type = bss, define = yes;
HEAP: load = SDRAM, type = bss, optional = yes;
STARTUP: load = ROM, type = ro;
ONCE: load = ROM, type = ro, optional = yes;
CODE: load = ROM, type = ro;
RODATA: load = ROM, type = ro;
VECTORS: load = ROM, type = ro, start = $FFFA;
}
FEATURES {
CONDES: segment = STARTUP,
type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__;
CONDES: segment = STARTUP,
type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__;
}
SYMBOLS {
# Define the stack size for the application
__STACKSIZE__: value = $0200, type = weak;
__STACKSTART__: type = weak, value = $0800; # 2k stack
}

View File

@@ -0,0 +1,23 @@
.export _init, _nmi_int, _irq_int
.code
_nmi_int:
_irq_int:
_init:
ldx #$ff
txs
lda #$00
jsr subroutine
sta $00
@1: bra @1
subroutine:
inc
jsr suborutine2
rts
suborutine2:
inc
rts

View File

@@ -0,0 +1,14 @@
; ---------------------------------------------------------------------------
; vectors.s
; ---------------------------------------------------------------------------
;
; Defines the interrupt vector table.
.import _init
.import _nmi_int, _irq_int
.segment "VECTORS"
.addr _nmi_int ; NMI vector
.addr _init ; Reset vector
.addr _irq_int ; IRQ/BRK vector