diff --git a/hw/efinix_fpga/simulation/src/sim_top.sv b/hw/efinix_fpga/simulation/src/sim_top.sv
index 4d18031799046efd2de66b274421ce0727fdd843..a01f70c183fd28eeb9d5fbf1b0c6bab8bb7ad6ee 100644
--- a/hw/efinix_fpga/simulation/src/sim_top.sv
+++ b/hw/efinix_fpga/simulation/src/sim_top.sv
@@ -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),
diff --git a/hw/efinix_fpga/src/sdram_adapter.sv b/hw/efinix_fpga/src/sdram_adapter.sv
index 9b0b7c02f08abffa835cd9736cbd908c8ca8ed4c..be3c8165dbd90d836164e773bf59ffa6bf8df48f 100644
--- a/hw/efinix_fpga/src/sdram_adapter.sv
+++ b/hw/efinix_fpga/src/sdram_adapter.sv
@@ -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
 
diff --git a/hw/efinix_fpga/src/super6502.sv b/hw/efinix_fpga/src/super6502.sv
index b0b1a49c1605cf8846953c62770efcc6660b9af2..5cdc89451157c74fdb5c24bd726201df66622282 100644
--- a/hw/efinix_fpga/src/super6502.sv
+++ b/hw/efinix_fpga/src/super6502.sv
@@ -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),
diff --git a/hw/efinix_fpga/super6502.xml b/hw/efinix_fpga/super6502.xml
index 1431efd41282139fe4575e74f1e2427d8da82090..55c88b176a47afe242e3f5004d2480070d12b591 100644
--- a/hw/efinix_fpga/super6502.xml
+++ b/hw/efinix_fpga/super6502.xml
@@ -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>
\ No newline at end of file
+</efx:project>
diff --git a/sw/Makefile b/sw/Makefile
index a47ed4284cc7051d9bda66b431b5b483e9fdd918..ad99e4005f7c378d425d6208b9d336484bd8adb3 100644
--- a/sw/Makefile
+++ b/sw/Makefile
@@ -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 $@
\ No newline at end of file
+	@$(MAKE) -C cc65  --no-print-directory $@
diff --git a/sw/test_code/indirect_test/Makefile b/sw/test_code/indirect_test/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..5fbaadcb2bb72ab77b3263c8942c969889c9c207
--- /dev/null
+++ b/sw/test_code/indirect_test/Makefile
@@ -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
+
diff --git a/sw/test_code/indirect_test/link.ld b/sw/test_code/indirect_test/link.ld
new file mode 100644
index 0000000000000000000000000000000000000000..66a42fef67750d7f7b4953983d592d51e117d612
--- /dev/null
+++ b/sw/test_code/indirect_test/link.ld
@@ -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
+}
diff --git a/sw/test_code/indirect_test/main.s b/sw/test_code/indirect_test/main.s
new file mode 100644
index 0000000000000000000000000000000000000000..65cf8410f66074ecfe777936dc3e20942a778061
--- /dev/null
+++ b/sw/test_code/indirect_test/main.s
@@ -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
\ No newline at end of file
diff --git a/sw/test_code/indirect_test/vectors.s b/sw/test_code/indirect_test/vectors.s
new file mode 100644
index 0000000000000000000000000000000000000000..81ae6e0f15c50a4957d465c2171dd362e312282a
--- /dev/null
+++ b/sw/test_code/indirect_test/vectors.s
@@ -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
\ No newline at end of file
diff --git a/sw/test_code/jsr_test/Makefile b/sw/test_code/jsr_test/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..262a351f1911f30ddda8900687104e184a0202ac
--- /dev/null
+++ b/sw/test_code/jsr_test/Makefile
@@ -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
+
diff --git a/sw/test_code/jsr_test/link.ld b/sw/test_code/jsr_test/link.ld
new file mode 100644
index 0000000000000000000000000000000000000000..66a42fef67750d7f7b4953983d592d51e117d612
--- /dev/null
+++ b/sw/test_code/jsr_test/link.ld
@@ -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
+}
diff --git a/sw/test_code/jsr_test/main.s b/sw/test_code/jsr_test/main.s
new file mode 100644
index 0000000000000000000000000000000000000000..4c74c59da2dbb37fbe216bc55e28042d3926844e
--- /dev/null
+++ b/sw/test_code/jsr_test/main.s
@@ -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
\ No newline at end of file
diff --git a/sw/test_code/jsr_test/vectors.s b/sw/test_code/jsr_test/vectors.s
new file mode 100644
index 0000000000000000000000000000000000000000..81ae6e0f15c50a4957d465c2171dd362e312282a
--- /dev/null
+++ b/sw/test_code/jsr_test/vectors.s
@@ -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
\ No newline at end of file