diff --git a/hw/efinix_fpga/addr_decode.sv b/hw/efinix_fpga/addr_decode.sv index bde918f..b137400 100644 --- a/hw/efinix_fpga/addr_decode.sv +++ b/hw/efinix_fpga/addr_decode.sv @@ -19,6 +19,6 @@ assign o_divider_cs = i_addr >= 16'hefe8 && i_addr <= 16'hefef; assign o_uart_cs = i_addr >= 16'hefe6 && i_addr <= 16'hefe7; assign o_spi_cs = i_addr >= 16'hefd8 && i_addr <= 16'hefdb; assign o_leds_cs = i_addr == 16'hefff; -assign o_sdram_cs = i_addr < 16'h8000; +assign o_sdram_cs = i_addr < 16'he000; endmodule \ No newline at end of file diff --git a/hw/efinix_fpga/debug_profile.wizard.json b/hw/efinix_fpga/debug_profile.wizard.json index f161bb2..34574c6 100644 --- a/hw/efinix_fpga/debug_profile.wizard.json +++ b/hw/efinix_fpga/debug_profile.wizard.json @@ -3,7 +3,7 @@ { "name": "la0", "type": "la", - "uuid": "fc5ad0b7db9846e2b64719110e7975d8", + "uuid": "376f85320e7b4d47a35d93dea8b58f08", "trigin_en": false, "trigout_en": false, "auto_inserted": true, @@ -21,48 +21,43 @@ "width": 1, "probe_type": 1 }, - { - "name": "cpu_sync", - "width": 1, - "probe_type": 1 - }, - { - "name": "cpu_resb", - "width": 1, - "probe_type": 1 - }, { "name": "cpu_addr", "width": 16, "probe_type": 1 }, { - "name": "cpu_phi2", + "name": "cpu_sync", "width": 1, "probe_type": 1 }, { - "name": "spi_clk", + "name": "cpu_rdy", "width": 1, "probe_type": 1 }, { - "name": "spi_mosi", + "name": "spi_controller/r_input_data", + "width": 8, + "probe_type": 1 + }, + { + "name": "spi_controller/r_output_data", + "width": 8, + "probe_type": 1 + }, + { + "name": "spi_controller/o_spi_clk", "width": 1, "probe_type": 1 }, { - "name": "sd_cs", + "name": "spi_controller/o_spi_mosi", "width": 1, "probe_type": 1 }, { - "name": "spi_miso", - "width": 1, - "probe_type": 1 - }, - { - "name": "spi_controller/active", + "name": "spi_controller/i_spi_miso", "width": 1, "probe_type": 1 } @@ -192,7 +187,7 @@ }, { "name": "la0_clk", - "net": "clk_50", + "net": "clk_2", "path": [] }, { @@ -241,123 +236,224 @@ "path": [] }, { - "name": "la0_probe2", - "net": "cpu_sync", - "path": [] - }, - { - "name": "la0_probe3", - "net": "cpu_resb", - "path": [] - }, - { - "name": "la0_probe4[0]", + "name": "la0_probe2[0]", "net": "cpu_addr[0]", "path": [] }, { - "name": "la0_probe4[1]", + "name": "la0_probe2[1]", "net": "cpu_addr[1]", "path": [] }, { - "name": "la0_probe4[2]", + "name": "la0_probe2[2]", "net": "cpu_addr[2]", "path": [] }, { - "name": "la0_probe4[3]", + "name": "la0_probe2[3]", "net": "cpu_addr[3]", "path": [] }, { - "name": "la0_probe4[4]", + "name": "la0_probe2[4]", "net": "cpu_addr[4]", "path": [] }, { - "name": "la0_probe4[5]", + "name": "la0_probe2[5]", "net": "cpu_addr[5]", "path": [] }, { - "name": "la0_probe4[6]", + "name": "la0_probe2[6]", "net": "cpu_addr[6]", "path": [] }, { - "name": "la0_probe4[7]", + "name": "la0_probe2[7]", "net": "cpu_addr[7]", "path": [] }, { - "name": "la0_probe4[8]", + "name": "la0_probe2[8]", "net": "cpu_addr[8]", "path": [] }, { - "name": "la0_probe4[9]", + "name": "la0_probe2[9]", "net": "cpu_addr[9]", "path": [] }, { - "name": "la0_probe4[10]", + "name": "la0_probe2[10]", "net": "cpu_addr[10]", "path": [] }, { - "name": "la0_probe4[11]", + "name": "la0_probe2[11]", "net": "cpu_addr[11]", "path": [] }, { - "name": "la0_probe4[12]", + "name": "la0_probe2[12]", "net": "cpu_addr[12]", "path": [] }, { - "name": "la0_probe4[13]", + "name": "la0_probe2[13]", "net": "cpu_addr[13]", "path": [] }, { - "name": "la0_probe4[14]", + "name": "la0_probe2[14]", "net": "cpu_addr[14]", "path": [] }, { - "name": "la0_probe4[15]", + "name": "la0_probe2[15]", "net": "cpu_addr[15]", "path": [] }, { - "name": "la0_probe5", - "net": "cpu_phi2", + "name": "la0_probe3", + "net": "cpu_sync", "path": [] }, { - "name": "la0_probe6", - "net": "spi_clk", + "name": "la0_probe4", + "net": "cpu_rdy", "path": [] }, + { + "name": "la0_probe5[0]", + "net": "r_input_data[0]", + "path": [ + "spi_controller" + ] + }, + { + "name": "la0_probe5[1]", + "net": "r_input_data[1]", + "path": [ + "spi_controller" + ] + }, + { + "name": "la0_probe5[2]", + "net": "r_input_data[2]", + "path": [ + "spi_controller" + ] + }, + { + "name": "la0_probe5[3]", + "net": "r_input_data[3]", + "path": [ + "spi_controller" + ] + }, + { + "name": "la0_probe5[4]", + "net": "r_input_data[4]", + "path": [ + "spi_controller" + ] + }, + { + "name": "la0_probe5[5]", + "net": "r_input_data[5]", + "path": [ + "spi_controller" + ] + }, + { + "name": "la0_probe5[6]", + "net": "r_input_data[6]", + "path": [ + "spi_controller" + ] + }, + { + "name": "la0_probe5[7]", + "net": "r_input_data[7]", + "path": [ + "spi_controller" + ] + }, + { + "name": "la0_probe6[0]", + "net": "r_output_data[0]", + "path": [ + "spi_controller" + ] + }, + { + "name": "la0_probe6[1]", + "net": "r_output_data[1]", + "path": [ + "spi_controller" + ] + }, + { + "name": "la0_probe6[2]", + "net": "r_output_data[2]", + "path": [ + "spi_controller" + ] + }, + { + "name": "la0_probe6[3]", + "net": "r_output_data[3]", + "path": [ + "spi_controller" + ] + }, + { + "name": "la0_probe6[4]", + "net": "r_output_data[4]", + "path": [ + "spi_controller" + ] + }, + { + "name": "la0_probe6[5]", + "net": "r_output_data[5]", + "path": [ + "spi_controller" + ] + }, + { + "name": "la0_probe6[6]", + "net": "r_output_data[6]", + "path": [ + "spi_controller" + ] + }, + { + "name": "la0_probe6[7]", + "net": "r_output_data[7]", + "path": [ + "spi_controller" + ] + }, { "name": "la0_probe7", - "net": "spi_mosi", - "path": [] + "net": "o_spi_clk", + "path": [ + "spi_controller" + ] }, { "name": "la0_probe8", - "net": "sd_cs", - "path": [] + "net": "o_spi_mosi", + "path": [ + "spi_controller" + ] }, { "name": "la0_probe9", - "net": "spi_miso", - "path": [] - }, - { - "name": "la0_probe10", - "net": "active", + "net": "i_spi_miso", "path": [ "spi_controller" ] @@ -380,7 +476,7 @@ { "name": "cpu_data_in", "width": 8, - "clk_domain": "clk_50", + "clk_domain": "clk_2", "selected_probe_type": "DATA AND TRIGGER", "child": [], "path": [], @@ -390,23 +486,7 @@ { "name": "cpu_rwb", "width": 1, - "clk_domain": "clk_50", - "selected_probe_type": "DATA AND TRIGGER", - "child": [], - "path": [] - }, - { - "name": "cpu_sync", - "width": 1, - "clk_domain": "clk_50", - "selected_probe_type": "DATA AND TRIGGER", - "child": [], - "path": [] - }, - { - "name": "cpu_resb", - "width": 1, - "clk_domain": "clk_50", + "clk_domain": "clk_2", "selected_probe_type": "DATA AND TRIGGER", "child": [], "path": [] @@ -414,7 +494,7 @@ { "name": "cpu_addr", "width": 16, - "clk_domain": "clk_50", + "clk_domain": "clk_2", "selected_probe_type": "DATA AND TRIGGER", "child": [], "path": [], @@ -422,49 +502,69 @@ "net_idx_right": 0 }, { - "name": "cpu_phi2", + "name": "cpu_sync", "width": 1, - "clk_domain": "clk_50", + "clk_domain": "clk_2", "selected_probe_type": "DATA AND TRIGGER", "child": [], "path": [] }, { - "name": "spi_clk", + "name": "cpu_rdy", "width": 1, - "clk_domain": "clk_50", + "clk_domain": "clk_2", "selected_probe_type": "DATA AND TRIGGER", "child": [], "path": [] }, { - "name": "spi_mosi", - "width": 1, - "clk_domain": "clk_50", + "name": "r_input_data", + "width": 8, + "clk_domain": "clk_2", "selected_probe_type": "DATA AND TRIGGER", "child": [], - "path": [] + "path": [ + "spi_controller" + ], + "net_idx_left": 7, + "net_idx_right": 0 }, { - "name": "sd_cs", - "width": 1, - "clk_domain": "clk_50", + "name": "r_output_data", + "width": 8, + "clk_domain": "clk_2", "selected_probe_type": "DATA AND TRIGGER", "child": [], - "path": [] + "path": [ + "spi_controller" + ], + "net_idx_left": 7, + "net_idx_right": 0 }, { - "name": "spi_miso", + "name": "o_spi_clk", "width": 1, - "clk_domain": "clk_50", + "clk_domain": "clk_2", "selected_probe_type": "DATA AND TRIGGER", "child": [], - "path": [] + "path": [ + "spi_controller" + ] }, { - "name": "active", + "name": "o_spi_mosi", "width": 1, - "clk_domain": "clk_50", + "clk_domain": "clk_2", + "selected_probe_type": "DATA AND TRIGGER", + "child": [], + "path": [ + "spi_controller" + ] + }, + { + "name": "i_spi_miso", + "width": 1, + "clk_domain": "clk_2", "selected_probe_type": "DATA AND TRIGGER", "child": [], "path": [ diff --git a/hw/efinix_fpga/init_hex.mem b/hw/efinix_fpga/init_hex.mem index ad3eb76..244cd15 100644 --- a/hw/efinix_fpga/init_hex.mem +++ b/hw/efinix_fpga/init_hex.mem @@ -1,257 +1,257 @@ @00000000 -8D 0E 02 8E 0F 02 8D 15 02 8E 16 02 88 B9 FF FF -8D 1F 02 88 B9 FF FF 8D 1E 02 8C 21 02 20 FF FF -A0 FF D0 E8 60 A2 FF 9A D8 A9 F0 85 00 A9 7E 85 -01 20 72 F8 20 F0 F6 20 45 F0 58 20 03 F1 6C FC -FF 20 E4 F6 00 A0 00 F0 07 A9 45 A2 F0 4C 00 02 -60 AD FF EF A2 00 60 8D FF EF 60 20 E9 F0 C9 0A -D0 05 A9 0D 20 E9 F0 60 DA 5A A8 B2 00 AA A9 1B -20 E9 F0 A9 5B 20 E9 F0 98 20 E9 F0 A9 3B 20 E9 -F0 8A 20 E9 F0 A9 48 20 E9 F0 7A FA 60 DA A9 1B -20 E9 F0 A9 63 20 E9 F0 68 60 40 DA BA 48 E8 E8 -BD 00 01 29 10 D0 06 68 FA 20 02 F1 40 4C AD F0 -48 A0 04 B1 00 09 40 20 D9 F0 88 B1 00 20 D9 F0 -88 10 F8 68 09 01 20 D9 F0 20 AC F7 60 A9 01 8D -DB EF 60 9C DB EF 60 A9 00 8D DA EF AD DB EF 30 -FB AD D9 EF 60 8D E6 EF 60 48 8D E6 EF AD E7 EF -89 02 D0 F9 68 60 AD E6 EF A2 00 60 AD E7 EF A2 -00 60 60 20 70 F7 A2 00 86 02 86 03 A9 00 20 DD -F7 20 49 F7 A9 B9 A2 F8 20 27 F7 20 45 F1 C9 00 -20 F5 F7 D0 03 4C 32 F1 A9 95 A2 F8 20 27 F7 4C -39 F1 A9 AA A2 F8 20 27 F7 4C 3C F1 4C 3C F1 A0 -0C 20 D7 F6 60 20 7D F7 A9 00 20 25 F8 20 B7 F2 -4C 7C F1 A0 00 A2 00 18 A9 01 71 00 91 00 A0 00 -A2 00 B1 00 C9 FF 20 FB F7 D0 03 4C 7C F1 A9 DB -A2 F8 20 27 F7 A2 00 A9 01 4C B3 F2 20 69 F4 A0 -01 91 00 C9 01 20 F5 F7 D0 C9 A2 00 A9 00 A0 06 -20 69 F8 A0 07 20 C1 F7 E0 03 D0 02 C9 E8 20 14 -F8 F0 03 4C A9 F1 4C B5 F1 A0 06 A2 00 A9 01 20 -C7 F6 4C 93 F1 A9 01 20 C8 F7 20 C3 F4 A0 01 A2 -00 B1 00 C9 01 20 F5 F7 D0 03 4C DB F1 A9 D1 A2 -F8 20 27 F7 A2 00 A9 01 4C B3 F2 A0 05 A2 00 B1 -00 C9 AA 20 F5 F7 D0 03 4C F2 F1 A2 00 A9 01 4C -B3 F2 A2 00 A9 00 A0 00 91 00 A0 00 A2 00 B1 00 -C9 FF 20 FB F7 D0 03 4C 18 F2 A9 C1 A2 F8 20 27 -F7 A2 00 A9 01 4C B3 F2 20 E5 F5 A0 01 91 00 A0 -01 A2 00 B1 00 C9 02 20 14 F8 D0 03 4C 36 F2 20 -3F F6 A0 01 91 00 A2 00 A9 00 A0 06 20 69 F8 A0 -07 20 C1 F7 E0 03 D0 02 C9 E8 20 14 F8 F0 03 4C -55 F2 4C 61 F2 A0 06 A2 00 A9 01 20 C7 F6 4C 3F -F2 A0 00 A2 00 18 A9 01 71 00 91 00 A0 01 A2 00 -B1 00 C9 00 20 F5 F7 D0 81 A2 00 A9 00 A0 06 20 -69 F8 A0 07 20 C1 F7 E0 03 D0 02 C9 E8 20 14 F8 -F0 03 4C 98 F2 4C A4 F2 A0 06 A2 00 A9 01 20 C7 -F6 4C 82 F2 A9 01 20 C8 F7 20 6B F5 A2 00 A9 00 -4C B3 F2 20 B1 F7 60 20 56 F7 A2 00 A9 00 20 D3 -F0 A2 00 A9 00 A0 01 20 69 F8 A0 02 20 C1 F7 E0 -03 D0 02 C9 E8 20 14 F8 F0 03 4C E0 F2 4C EC F2 -A0 01 A2 00 A9 01 20 C7 F6 4C CA F2 A2 00 A9 FF -20 D9 F0 A2 00 A9 00 20 D3 F0 A2 00 A9 00 A0 00 -91 00 A0 00 A2 00 B1 00 C9 50 20 14 F8 F0 03 4C -15 F3 4C 2A F3 A2 00 A9 FF 20 D9 F0 A0 00 A2 00 -18 A9 01 71 00 91 00 4C 02 F3 20 A7 F7 60 A9 00 -20 25 F8 20 40 F7 4C 59 F3 A0 01 A2 00 18 A9 01 -71 00 91 00 A0 01 A2 00 B1 00 C9 09 A9 00 A2 00 -2A D0 03 4C 59 F3 4C 6B F3 A2 00 A9 FF 20 D9 F0 -A0 00 91 00 C9 FF 20 FB F7 D0 CE A0 00 A2 00 B1 -00 4C 74 F3 20 99 F7 60 20 3B F8 A0 01 20 C1 F7 -20 3B F8 20 2E F3 A0 00 20 51 F8 A0 01 20 C1 F7 -1A D0 01 E8 20 3B F8 A2 00 A9 FF 20 D9 F0 A0 00 -20 51 F8 20 99 F7 60 20 3B F8 A0 01 20 C1 F7 20 -3B F8 20 2E F3 A0 00 20 51 F8 A0 01 20 C1 F7 A0 -00 20 B6 F7 C9 02 A9 00 A2 00 2A D0 03 4C D3 F3 -4C E6 F3 A0 01 20 C1 F7 1A D0 01 E8 20 3B F8 A2 -00 A9 04 20 2D F4 20 99 F7 60 20 3B F8 A0 01 20 -C1 F7 20 3B F8 20 2E F3 A0 00 20 51 F8 A0 01 20 -C1 F7 A0 00 20 B6 F7 C9 02 A9 00 A2 00 2A D0 03 -4C 16 F4 4C 29 F4 A0 01 20 C1 F7 1A D0 01 E8 20 -3B F8 A2 00 A9 04 20 2D F4 20 99 F7 60 20 25 F8 -4C 52 F4 A0 02 20 C1 F7 20 3B F8 A2 00 A9 FF 48 -A0 03 A2 00 A9 01 20 C7 F6 68 20 D9 F0 A0 00 20 -51 F8 A0 00 B1 00 08 A0 00 A2 00 B1 00 38 E9 01 -91 00 28 D0 CE 20 A7 F7 60 20 40 F7 A2 00 A9 FF -20 D9 F0 A2 00 A9 00 20 CD F0 A2 00 A9 FF 20 D9 -F0 A2 00 A9 00 20 25 F8 A2 00 86 02 86 03 A9 00 -20 DD F7 A2 00 A9 94 20 B0 F0 20 2E F3 A0 00 91 -00 A2 00 A9 FF 20 D9 F0 A2 00 A9 00 20 D3 F0 A2 -00 A9 FF 20 D9 F0 A0 00 A2 00 B1 00 4C BF F4 20 -8A F7 60 20 3B F8 A2 00 A9 FF 20 D9 F0 A2 00 A9 -00 20 CD F0 A2 00 A9 FF 20 D9 F0 A2 00 A9 08 20 -25 F8 A2 01 A9 00 85 02 A9 00 85 03 A9 AA 20 DD -F7 A2 00 A9 86 20 B0 F0 A0 01 20 C1 F7 20 EA F3 -A2 00 A9 FF 20 D9 F0 A2 00 A9 00 20 D3 F0 A2 00 -A9 FF 20 D9 F0 20 99 F7 60 20 3B F8 A2 00 A9 FF -20 D9 F0 A2 00 A9 00 20 CD F0 A2 00 A9 FF 20 D9 -F0 A2 00 A9 0D 20 25 F8 A2 00 86 02 86 03 A9 00 -20 DD F7 A2 00 A9 00 20 B0 F0 A0 01 20 C1 F7 20 -78 F3 A2 00 A9 FF 20 D9 F0 A2 00 A9 00 20 D3 F0 -A2 00 A9 FF 20 D9 F0 20 99 F7 60 20 3B F8 20 40 -F7 A2 00 A9 FF 20 D9 F0 A2 00 A9 00 20 CD F0 A2 -00 A9 FF 20 D9 F0 A0 00 91 00 A0 00 A2 00 B1 00 -C9 FF 20 F5 F7 D0 03 4C AB F5 4C 9D F5 A2 00 A9 -FF 20 D9 F0 C9 FF 20 F5 F7 D0 F2 A2 00 A9 3A 20 -25 F8 A2 00 86 02 86 03 A9 00 20 DD F7 A2 00 A9 -00 20 B0 F0 A0 02 20 C1 F7 20 A7 F3 A2 00 A9 FF -20 D9 F0 A2 00 A9 00 20 D3 F0 A2 00 A9 FF 20 D9 -F0 20 A7 F7 60 20 40 F7 A2 00 A9 FF 20 D9 F0 A2 -00 A9 00 20 CD F0 A2 00 A9 FF 20 D9 F0 A2 00 A9 -37 20 25 F8 A2 00 86 02 86 03 A9 00 20 DD F7 A2 -00 A9 00 20 B0 F0 20 2E F3 A0 00 91 00 A2 00 A9 -FF 20 D9 F0 A2 00 A9 00 20 D3 F0 A2 00 A9 FF 20 -D9 F0 A0 00 A2 00 B1 00 4C 3B F6 20 8A F7 60 20 -40 F7 A2 00 A9 FF 20 D9 F0 A2 00 A9 00 20 CD F0 -A2 00 A9 FF 20 D9 F0 A2 00 A9 29 20 25 F8 A2 00 -86 02 A9 40 85 03 A9 00 20 DD F7 A2 00 A9 00 20 -B0 F0 20 2E F3 A0 00 91 00 A2 00 A9 FF 20 D9 F0 -A2 00 A9 00 20 D3 F0 A2 00 A9 FF 20 D9 F0 A0 00 -A2 00 B1 00 4C 97 F6 20 8A F7 60 20 3B F8 20 70 -F7 A0 05 A2 00 B1 00 4C AA F6 A0 0E 20 D7 F6 60 -20 3B F8 20 70 F7 A0 03 A2 00 B1 00 4C BF F6 A0 -0E 20 D7 F6 60 A0 00 18 71 00 91 00 48 C8 8A 71 -00 91 00 AA 68 60 C8 48 18 98 65 00 85 00 90 02 -E6 01 68 60 A0 00 F0 07 A9 45 A2 F0 4C 00 02 60 -A9 00 85 08 A9 F0 85 09 A9 00 85 0A A9 02 85 0B -A2 DA A9 FF 85 10 A0 00 E8 F0 0D B1 08 91 0A C8 -D0 F6 E6 09 E6 0B D0 F0 E6 10 D0 EF 60 85 08 86 -09 20 68 F0 4C 2B F7 85 08 86 09 A0 00 B1 08 F0 -0E C8 84 10 20 5B F0 A4 10 D0 F2 E6 09 D0 EE 60 -A4 00 D0 02 C6 01 C6 00 60 A5 00 38 E9 02 85 00 -90 01 60 C6 01 60 A5 00 38 E9 03 85 00 90 01 60 -C6 01 60 A5 00 38 E9 04 85 00 90 01 60 C6 01 60 -A5 00 38 E9 06 85 00 90 01 60 C6 01 60 A5 00 38 -E9 07 85 00 90 01 60 C6 01 60 E6 00 D0 02 E6 01 -60 A0 01 B1 00 AA 88 B1 00 E6 00 F0 05 E6 00 F0 -03 60 E6 00 E6 01 60 A0 03 4C D7 F6 A0 05 4C D7 -F6 A0 08 4C D7 F6 85 08 86 09 A2 00 B1 08 60 A0 -01 B1 00 AA 88 B1 00 60 A2 00 18 65 00 48 8A 65 -01 AA 68 60 A9 00 AA A0 00 84 02 84 03 48 20 63 -F7 A0 03 A5 03 91 00 88 A5 02 91 00 88 8A 91 00 -68 88 91 00 60 D0 06 A2 00 8A 60 D0 FA A2 00 A9 -01 60 F0 F9 30 F7 A2 00 8A 60 F0 02 10 EF A2 00 -8A 60 F0 E9 90 E7 A2 00 8A 60 F0 DB A2 00 8A 2A -60 A0 00 B1 00 A4 00 F0 07 C6 00 A0 00 91 00 60 -C6 01 C6 00 91 00 60 A9 00 A2 00 48 A5 00 38 E9 -02 85 00 B0 02 C6 01 A0 01 8A 91 00 68 88 91 00 -60 48 84 10 A0 01 B1 00 85 09 88 B1 00 85 08 A4 -10 68 91 08 4C 99 F7 A0 00 91 00 C8 48 8A 91 00 -68 60 A9 25 85 08 A9 02 85 09 A9 00 A8 A2 02 F0 -0A 91 08 C8 D0 FB E6 09 CA D0 F6 C0 00 F0 05 91 -08 C8 D0 F7 60 45 72 72 6F 72 20 69 6E 69 74 20 -53 44 20 43 41 52 44 0D 0A 00 53 44 20 43 61 72 -64 20 69 6E 69 74 0D 0A 00 53 74 61 72 74 0D 0A -00 6F 70 5F 63 6F 6E 64 20 65 72 72 6F 72 0D 0A -00 49 46 20 43 6F 6E 64 0D 0A 00 47 6F 20 49 44 -4C 45 0D 0A 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 9A F0 25 F0 9B F0 +00 80 4C 00 00 8D 13 92 8E 14 92 8D 1A 92 8E 1B +92 88 B9 FF FF 8D 24 92 88 B9 FF FF 8D 23 92 8C +26 92 20 FF FF A0 FF D0 E8 60 00 00 90 FD 00 00 +00 00 A2 FF 9A D8 A9 00 85 02 A9 DF 85 03 20 08 +FE 20 B9 FA 20 52 F0 58 20 69 F2 6C FC FF 20 AD +FA 00 A0 00 F0 07 A9 52 A2 F0 4C 05 92 60 AD FF +EF A2 00 60 8D FF EF 60 20 4F F2 C9 0A D0 05 A9 +0D 20 4F F2 60 DA 5A A8 B2 02 AA A9 1B 20 4F F2 +A9 5B 20 4F F2 98 20 4F F2 A9 3B 20 4F F2 8A 20 +4F F2 A9 48 20 4F F2 7A FA 60 DA A9 1B 20 4F F2 +A9 63 20 4F F2 68 60 40 DA BA 48 E8 E8 BD 00 01 +29 10 D0 06 68 FA 20 68 F2 40 68 FA 7C BF F0 C5 +F0 C9 F0 CA F0 20 9A F0 40 40 20 68 F0 40 48 A0 +04 B1 02 09 40 20 3F F2 88 B1 02 20 3F F2 88 10 +F8 68 09 01 20 3F F2 20 A9 FB 60 A2 08 A9 FF 20 +3F F2 C9 FF D0 03 CA D0 F4 60 85 0A 86 0B 20 EB +F0 92 0A A9 FF 20 3F F2 A0 01 91 0A 20 96 FB 60 +AA 20 E4 FC A9 FF 20 3F F2 92 0A E6 0A D0 02 E6 +0B CA D0 F0 60 85 0A 86 0B 20 EB F0 C9 02 B0 12 +E6 0A D0 02 E6 0A A5 0A A6 0B 20 11 FD A9 04 20 +10 F1 60 48 A9 FF 20 3F F2 A9 00 20 33 F2 A9 FF +20 3F F2 68 20 CE F0 20 EB F0 A8 A9 FF 20 3F F2 +A9 00 20 39 F2 A9 FF 20 3F F2 98 A2 00 60 A9 00 +20 39 F2 20 8B F1 A9 FF 20 3F F2 A9 00 20 39 F2 +A2 50 A9 FF 20 3F F2 CA D0 F8 60 A2 01 A9 C8 3A +D0 FD CA D0 F8 60 85 0C 86 0D A9 FF 92 0C 20 E4 +FC A5 02 85 0E A5 03 85 0F 20 51 FB A0 00 B1 0E +91 02 C8 B1 0E 91 02 C8 B1 0E 91 02 C8 B1 0E 91 +02 A9 FF 20 3F F2 A9 00 20 33 F2 A9 FF 20 3F F2 +A9 11 A0 04 91 02 A9 00 20 CE F0 20 EB F0 C9 FF +F0 3F 85 14 A0 00 A9 FF 20 3F F2 85 13 A5 13 C9 +FF D0 05 C8 D0 F0 80 23 A2 02 A0 00 A9 FF 20 3F +F2 92 0A E6 0A D0 02 E6 0B 88 D0 F0 A0 00 CA D0 +EB A9 FF 20 3F F2 A9 FF 20 3F F2 A5 13 92 0C A5 +14 48 A9 FF 20 3F F2 A9 00 20 39 F2 A9 FF 20 3F +F2 68 60 A9 01 8D DB EF 60 9C DB EF 60 A9 00 8D +DA EF AD DB EF 30 FB AD D9 EF 60 8D E6 EF 60 48 +8D E6 EF AD E7 EF 89 02 D0 F9 68 60 AD E6 EF A2 +00 60 AD E7 EF A2 00 60 60 20 74 FB A2 00 86 04 +86 05 A9 00 20 0B FC 20 5A FB A9 4D A2 FE 20 1A +FB 20 3A F3 C9 00 20 B8 FC D0 03 4C 98 F2 A9 45 +A2 FE 20 1A FB 4C 2E F3 A9 3B A2 FE 20 1A FB A0 +05 20 C7 FB 20 0B FC AD 00 92 AE 01 92 20 11 FD +A9 0C 20 D8 FB 20 96 F1 A0 07 91 02 A0 07 A2 00 +B1 02 C9 00 20 BE FC D0 03 4C DC F2 A0 06 A2 00 +B1 02 C9 FE 20 BE FC F0 03 4C E5 F2 A2 00 A9 00 +D0 03 4C E9 F2 A2 00 A9 01 D0 03 4C FA F2 AD 00 +92 AE 01 92 20 3C F6 4C 2B F3 A0 06 A2 00 B1 02 +A2 00 29 F0 20 9F FA D0 03 4C 16 F3 A9 45 A2 FE +20 1A FB 4C 2B F3 A9 2B A2 FE 20 11 FD A0 08 A2 +00 B1 02 20 11 FD A0 04 20 E6 FA 6C 00 92 4C 31 +F3 4C 31 F3 A0 0C 20 85 FA 60 20 81 FB A9 00 20 +FB FC 20 6E F1 4C 71 F3 A0 00 A2 00 18 A9 01 71 +02 91 02 A0 00 A2 00 B1 02 C9 FF 20 BE FC D0 03 +4C 71 F3 A9 6F A2 FE 20 1A FB A2 00 A9 01 4C A8 +F4 20 AC F4 A0 01 91 02 C9 01 20 B8 FC D0 C9 A2 +00 A9 00 A0 06 20 29 FD A0 07 20 BE FB E0 03 D0 +02 C9 E8 20 D7 FC F0 03 4C 9E F3 4C AA F3 A0 06 +A2 00 A9 01 20 75 FA 4C 88 F3 A9 01 20 D8 FB 20 +C9 F4 A0 01 A2 00 B1 02 C9 01 20 B8 FC D0 03 4C +D0 F3 A9 65 A2 FE 20 1A FB A2 00 A9 01 4C A8 F4 +A0 05 A2 00 B1 02 C9 AA 20 B8 FC D0 03 4C E7 F3 +A2 00 A9 01 4C A8 F4 A2 00 A9 00 A0 00 91 02 A0 +00 A2 00 B1 02 C9 FF 20 BE FC D0 03 4C 0D F4 A9 +55 A2 FE 20 1A FB A2 00 A9 01 4C A8 F4 20 EB F5 +A0 01 91 02 A0 01 A2 00 B1 02 C9 02 20 D7 FC D0 +03 4C 2B F4 20 08 F6 A0 01 91 02 A2 00 A9 00 A0 +06 20 29 FD A0 07 20 BE FB E0 03 D0 02 C9 E8 20 +D7 FC F0 03 4C 4A F4 4C 56 F4 A0 06 A2 00 A9 01 +20 75 FA 4C 34 F4 A0 00 A2 00 18 A9 01 71 02 91 +02 A0 01 A2 00 B1 02 C9 00 20 B8 FC D0 81 A2 00 +A9 00 A0 06 20 29 FD A0 07 20 BE FB E0 03 D0 02 +C9 E8 20 D7 FC F0 03 4C 8D F4 4C 99 F4 A0 06 A2 +00 A9 01 20 75 FA 4C 77 F4 A9 01 20 D8 FB 20 71 +F5 A2 00 A9 00 4C A8 F4 20 AE FB 60 A2 00 A9 00 +20 FB FC A2 00 86 04 86 05 A9 00 20 0B FC A2 00 +A9 94 20 43 F1 4C C8 F4 60 20 11 FD A2 00 A9 FF +20 3F F2 A2 00 A9 00 20 33 F2 A2 00 A9 FF 20 3F +F2 A2 00 A9 08 20 FB FC A2 01 A9 00 85 04 A9 00 +85 05 A9 AA 20 0B FC A2 00 A9 86 20 CE F0 A0 01 +20 BE FB 20 25 F1 A2 00 A9 FF 20 3F F2 A2 00 A9 +00 20 39 F2 A2 00 A9 FF 20 3F F2 20 96 FB 60 20 +11 FD A2 00 A9 FF 20 3F F2 A2 00 A9 00 20 33 F2 +A2 00 A9 FF 20 3F F2 A2 00 A9 0D 20 FB FC A2 00 +86 04 86 05 A9 00 20 0B FC A2 00 A9 00 20 CE F0 +A0 01 20 BE FB 20 FA F0 A2 00 A9 FF 20 3F F2 A2 +00 A9 00 20 39 F2 A2 00 A9 FF 20 3F F2 20 96 FB +60 20 11 FD 20 51 FB A2 00 A9 FF 20 3F F2 A2 00 +A9 00 20 33 F2 A2 00 A9 FF 20 3F F2 A0 00 91 02 +A0 00 A2 00 B1 02 C9 FF 20 B8 FC D0 03 4C B1 F5 +4C A3 F5 A2 00 A9 FF 20 3F F2 C9 FF 20 B8 FC D0 +F2 A2 00 A9 3A 20 FB FC A2 00 86 04 86 05 A9 00 +20 0B FC A2 00 A9 00 20 CE F0 A0 02 20 BE FB 20 +25 F1 A2 00 A9 FF 20 3F F2 A2 00 A9 00 20 39 F2 +A2 00 A9 FF 20 3F F2 20 A4 FB 60 A2 00 A9 37 20 +FB FC A2 00 86 04 86 05 A9 00 20 0B FC A2 00 A9 +00 20 43 F1 4C 07 F6 60 A2 00 A9 29 20 FB FC A2 +00 86 04 A9 40 85 05 A9 00 20 0B FC A2 00 A9 00 +20 43 F1 4C 26 F6 60 20 11 FD 20 74 FB A0 03 A2 +00 B1 02 4C 36 F6 A0 0E 20 85 FA 60 20 11 FD A9 +00 20 FB FC 20 5A FB A2 00 A9 00 A0 00 20 29 FD +A0 01 20 BE FB E0 02 20 D7 FC F0 03 4C 62 F6 4C +C4 F6 A9 79 A2 FE 20 11 FD A0 06 20 BE FB A0 00 +20 B3 FB 20 11 FD A0 07 A2 00 A9 01 20 75 FA A0 +04 20 E6 FA A0 02 A2 00 B1 02 C9 1F 20 BE FC D0 +03 4C A6 F6 A9 7D A2 FE 20 1A FB A2 00 A9 00 A0 +02 91 02 4C B8 F6 A2 00 A9 20 20 68 F0 A0 02 A2 +00 18 A9 01 71 02 91 02 A0 00 A2 00 A9 01 20 75 +FA 4C 50 F6 A9 7D A2 FE 20 1A FB 20 A9 FB 60 A0 +00 B1 18 E6 18 D0 02 E6 19 60 AD 3D 92 8D 38 92 +20 7B F7 A9 38 A2 92 20 11 FD 20 F2 FC 4C 02 92 +A5 16 38 E9 02 85 16 B0 02 C6 17 60 AD 42 92 D0 +11 20 19 F7 4C 98 FA AD 42 92 D0 06 20 19 F7 4C +92 FA 20 19 F7 85 04 86 05 20 F0 F6 A0 01 B1 16 +AA 88 B1 16 60 A0 00 84 0A 84 0B B1 18 38 E9 30 +90 2C C9 0A B0 28 20 D3 F6 48 A5 0A A6 0B 06 0A +26 0B 06 0A 26 0B 65 0A 85 0A 8A 65 0B 85 0B 06 +0A 26 0B 68 65 0A 85 0A 90 D1 E6 0B B0 CD A5 0A +A6 0B 60 AC 44 92 EE 44 92 99 45 92 60 A9 45 A2 +92 18 6D 44 92 90 01 E8 4C 11 FD A5 1A A6 1B 4C +11 FD 20 DA F6 EE 3E 92 D0 F8 EE 3F 92 D0 F3 60 +20 7B F7 AD 59 92 AE 5A 92 20 11 FD AD 5B 92 AE +5C 92 20 11 FD 4C 02 92 84 0A 20 0B FC 20 6D F7 +A5 0A 4C 3B FC 84 0A 20 0B FC 20 6D F7 A5 0A 4C +7C FC 48 A0 05 B9 16 00 99 32 92 88 10 F7 68 85 +16 86 17 20 8E FB 85 18 86 19 20 8E FB 85 1A 86 +1B A9 00 A8 91 1A C8 91 1A C8 B1 1A 8D 03 92 C8 +B1 1A 8D 04 92 A5 18 85 0A A5 19 85 0B A0 00 B1 +18 F0 0B C9 25 F0 07 C8 D0 F5 E6 19 D0 F1 98 18 +65 18 85 18 90 02 E6 19 38 E5 0A 85 0C A5 19 E5 +0B 85 0D 05 0C F0 25 20 74 FB A0 05 A5 1B 91 02 +88 A5 1A 91 02 88 A5 0B 91 02 88 A5 0A 91 02 88 +A5 0D 91 02 88 A5 0C 91 02 20 02 92 20 CF F6 AA +D0 0B A2 05 BD 32 92 95 16 CA 10 F8 60 C9 25 D0 +09 B1 18 C9 25 D0 09 20 D3 F6 20 DD F6 4C F5 F7 +A9 00 A2 0B 9D 39 92 CA 10 FA B1 18 C9 2D D0 05 +8E 39 92 F0 19 C9 2B D0 05 8E 3A 92 F0 10 C9 20 +D0 05 8E 3B 92 F0 07 C9 23 D0 09 8E 3C 92 20 D3 +F6 4C 7A F8 A2 20 C9 30 D0 06 AA 20 D3 F6 B1 18 +8E 3D 92 C9 2A D0 09 20 D3 F6 20 19 F7 4C C3 F8 +20 25 F7 8D 3E 92 8E 3F 92 8C 40 92 8C 41 92 B1 +18 C9 2E D0 1B 20 D3 F6 B1 18 C9 2A D0 09 20 D3 +F6 20 19 F7 4C EA F8 20 25 F7 8D 40 92 8E 41 92 +B1 18 C9 7A F0 19 C9 68 F0 15 C9 74 F0 11 C9 6A +F0 08 C9 4C F0 04 C9 6C D0 0B A9 FF 8D 42 92 20 +D3 F6 4C F0 F8 8C 44 92 A2 45 8E 59 92 A2 92 8E +5A 92 20 D3 F6 C9 63 D0 0D 20 19 F7 8D 45 92 A2 +00 A9 01 4C 1C FA C9 64 F0 04 C9 69 D0 2D A2 00 +AD 3B 92 F0 02 A2 20 AD 3A 92 F0 02 A2 2B 8E 43 +92 20 07 F7 A4 05 30 0B AC 43 92 F0 06 8C 45 92 +EE 44 92 A0 0A 20 A8 F7 4C 13 FA C9 6E D0 15 20 +19 F7 85 0A 86 0B A0 00 B1 1A 91 0A C8 B1 1A 91 +0A 4C F5 F7 C9 6F D0 27 20 07 F7 AC 3C 92 F0 17 +48 86 12 05 12 05 04 05 05 0D 40 92 0D 41 92 F0 +06 A9 30 20 63 F7 68 A0 08 20 A8 F7 4C 13 FA C9 +70 D0 0D A2 00 8E 42 92 E8 8E 3C 92 A9 78 D0 27 +C9 73 D0 0C 20 19 F7 8D 59 92 8E 5A 92 4C 13 FA +C9 75 D0 0B 20 FC F6 A0 0A 20 B5 F7 4C 13 FA C9 +78 F0 04 C9 58 D0 29 48 AD 3C 92 F0 0A A9 30 20 +63 F7 A9 58 20 63 F7 20 FC F6 A0 10 20 B5 F7 68 +C9 78 D0 09 AD 59 92 AE 5A 92 20 69 FD 4C 13 FA +4C F5 F7 AD 59 92 AE 5A 92 20 53 FD 8D 5B 92 8E +5C 92 AD 40 92 0D 41 92 F0 15 AE 40 92 EC 5B 92 +AD 41 92 A8 ED 5C 92 B0 06 8E 5B 92 8C 5C 92 38 +AD 3E 92 ED 5B 92 AA AD 3F 92 ED 5C 92 B0 03 A9 +00 AA 49 FF 8D 3F 92 8A 49 FF 8D 3E 92 AD 39 92 +D0 03 20 85 F7 20 90 F7 AD 39 92 F0 03 20 85 F7 +4C F5 F7 A0 00 18 71 02 91 02 48 C8 8A 71 02 91 +02 AA 68 60 C8 48 18 98 65 02 85 02 90 02 E6 03 +68 60 A0 FF E0 80 B0 02 A0 00 84 04 84 05 60 E0 +00 D0 06 AA D0 03 A9 01 60 A2 00 8A 60 A0 00 F0 +07 A9 52 A2 F0 4C 05 92 60 A9 00 85 0A A9 F0 85 +0B A9 00 85 0C A9 92 85 0D A2 CD A9 FF 85 12 A0 +00 E8 F0 0D B1 0A 91 0C C8 D0 F6 E6 0B E6 0D D0 +F0 E6 12 D0 EF 60 8C 5D 92 88 88 98 18 65 02 85 +0A A6 03 90 01 E8 86 0B A0 01 B1 0A AA 88 B1 0A +20 11 FD A5 0A A6 0B 20 D8 FD AC 5D 92 4C 85 FA +85 0A 86 0B 20 75 F0 4C 1E FB 85 0A 86 0B A0 00 +B1 0A F0 0E C8 84 12 20 68 F0 A4 12 D0 F2 E6 0B +D0 EE 60 E0 00 D0 15 4A AA BD A7 FE 90 05 4A 4A +4A 4A 18 29 0F AA BD 9C FE A2 00 60 38 A9 00 AA +60 A4 02 D0 02 C6 03 C6 02 60 A5 02 38 E9 02 85 +02 90 01 60 C6 03 60 A5 02 38 E9 04 85 02 90 01 +60 C6 03 60 A5 02 38 E9 06 85 02 90 01 60 C6 03 +60 A5 02 38 E9 07 85 02 90 01 60 C6 03 60 A0 01 +B1 02 AA 88 B1 02 E6 02 F0 05 E6 02 F0 03 60 E6 +02 E6 03 60 A0 03 4C 85 FA A0 05 4C 85 FA A0 08 +4C 85 FA 85 0A 86 0B A2 00 B1 0A 60 A0 01 B1 02 +AA 88 B1 02 60 A0 03 B1 02 85 05 88 B1 02 85 04 +88 B1 02 AA 88 B1 02 60 A2 00 18 65 02 48 8A 65 +03 AA 68 60 18 49 FF 69 01 48 8A 49 FF 69 00 AA +A5 04 49 FF 69 00 85 04 A5 05 49 FF 69 00 85 05 +68 60 A9 00 AA A0 00 84 04 84 05 48 20 67 FB A0 +03 A5 05 91 02 88 A5 04 91 02 88 8A 91 02 68 88 +91 02 60 85 12 20 8E FB 85 0C 86 0D 85 0E 86 0F +20 E4 FC 20 8E FB 85 04 86 05 60 20 23 FC A6 05 +A4 12 C0 0A D0 39 A5 04 05 0B 05 0A D0 11 E0 80 +D0 0D A0 0B B9 90 FE 91 0C 88 10 F8 4C B3 FC 8A +10 1D A9 2D A0 00 91 0C E6 0C D0 02 E6 0D A5 0A +A6 0B 20 E4 FB 85 0A 86 0B 4C 7F FC 20 23 FC A9 +00 48 A0 20 A9 00 06 0A 26 0B 26 04 26 05 2A C5 +12 90 04 E5 12 E6 0A 88 D0 EC A8 B9 80 FE 48 A5 +0A 05 0B 05 04 05 05 D0 D9 A0 00 68 91 0C F0 03 +C8 D0 F8 A5 0E A6 0F 60 D0 06 A2 00 8A 60 D0 FA +A2 00 A9 01 60 F0 F9 30 F7 A2 00 8A 60 F0 02 10 +EF A2 00 8A 60 F0 E9 90 E7 A2 00 8A 60 F0 DB A2 +00 8A 2A 60 A0 01 B1 02 85 0B 88 B1 02 85 0A 4C +96 FB A9 01 4C 0F FD A0 00 B1 02 A4 02 F0 07 C6 +02 A0 00 91 02 60 C6 03 C6 02 91 02 60 A9 00 A2 +00 48 A5 02 38 E9 02 85 02 B0 02 C6 03 A0 01 8A +91 02 68 88 91 02 60 A0 00 91 02 C8 48 8A 91 02 +68 60 85 0C 86 0D 20 E4 FC B1 0A D1 0C D0 0C AA +F0 10 C8 D0 F4 E6 0B E6 0D D0 EE B0 03 A2 FF 60 +A2 01 60 85 0C 86 0D A2 00 A0 00 B1 0C F0 08 C8 +D0 F9 E6 0D E8 D0 F4 98 60 85 0A 86 0B 85 0C 86 +0D A0 00 B1 0A F0 14 20 37 FB 29 02 F0 06 B1 0A +69 20 91 0A C8 D0 EC E6 0B D0 E8 A5 0C A6 0D 60 +20 8E FB 85 0C 86 0D E8 8E 31 92 AA E8 8E 30 92 +20 E4 FC 20 8E FB 85 0E 86 0F A0 00 84 12 B1 0E +18 65 0C 91 0E C8 B1 0E 65 0D 91 0E CE 30 92 F0 +11 A4 12 B1 0A C8 D0 02 E6 0B 84 12 20 68 F0 4C +BC FD CE 31 92 D0 EA 60 85 0A 86 0B A9 00 8D 2A +92 8D 2B 92 A0 01 B1 02 AA 88 B1 02 20 11 FD A0 +02 A9 2A 91 02 C8 A9 92 91 02 A5 0A A6 0B 20 C2 +F7 AD 2A 92 AE 2B 92 60 A9 32 85 0A A9 92 85 0B +A9 00 A8 A2 00 F0 0A 91 0A C8 D0 FB E6 0B CA D0 +F6 C0 2C F0 05 91 0A C8 D0 F7 60 62 61 64 20 74 +6F 6B 65 6E 3A 20 25 78 0D 0A 00 53 75 63 63 65 +73 73 0D 0A 00 45 72 72 6F 72 0D 0A 00 53 74 61 +72 74 0D 0A 00 6F 70 5F 63 6F 6E 64 20 65 72 72 +6F 72 0D 0A 00 49 46 20 43 6F 6E 64 0D 0A 00 47 +6F 20 49 44 4C 45 0D 0A 00 25 32 78 00 0D 0A 00 +30 31 32 33 34 35 36 37 38 39 41 42 43 44 45 46 +2D 32 31 34 37 34 38 33 36 34 38 00 00 01 02 0C +09 0A 10 40 50 A0 D0 66 66 66 66 A6 88 88 66 66 +66 66 66 66 66 66 66 09 00 00 00 00 00 00 00 33 +33 33 33 33 00 00 00 50 55 55 25 22 22 22 22 22 +22 22 22 22 02 00 00 40 44 44 14 11 11 11 11 11 +11 11 11 11 01 00 70 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 A7 F0 32 F0 A8 F0 diff --git a/hw/efinix_fpga/ip/uart/settings.json b/hw/efinix_fpga/ip/uart/settings.json index cee281a..a571cf2 100644 --- a/hw/efinix_fpga/ip/uart/settings.json +++ b/hw/efinix_fpga/ip/uart/settings.json @@ -23,12 +23,12 @@ }, "output": { "external_source_source": [ - "/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/uart_tmpl.v", - "/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/uart.v", "/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/uart_tmpl.vhd", - "/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/uart_define.vh" + "/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/uart_define.vh", + "/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/uart_tmpl.v", + "/home/byron/Projects/super6502/hw/efinix_fpga/ip/uart/uart.v" ] }, "sw_version": "2023.1.150", - "generated_date": "2023-07-23T03:23:04.338270" + "generated_date": "2023-08-06T21:23:16.380430" } \ No newline at end of file diff --git a/hw/efinix_fpga/ip/uart/uart.v b/hw/efinix_fpga/ip/uart/uart.v index 3814be2..ae1a2df 100644 --- a/hw/efinix_fpga/ip/uart/uart.v +++ b/hw/efinix_fpga/ip/uart/uart.v @@ -43,7 +43,7 @@ // //////////////////////////////////////////////////////////////////////////////// -`define IP_UUID _8d7ceb45e0e64e208e634a02f6a59365 +`define IP_UUID _d5f4d7c01b1345bca7e33275f3464327 `define IP_NAME_CONCAT(a,b) a``b `define IP_MODULE_NAME(name) `IP_NAME_CONCAT(name,`IP_UUID) module uart ( diff --git a/hw/efinix_fpga/super6502.xml b/hw/efinix_fpga/super6502.xml index 495eacf..44c05a4 100644 --- a/hw/efinix_fpga/super6502.xml +++ b/hw/efinix_fpga/super6502.xml @@ -1,5 +1,5 @@ - + @@ -100,7 +100,7 @@ - + diff --git a/sw/bootloader/Makefile b/sw/bios/Makefile similarity index 55% rename from sw/bootloader/Makefile rename to sw/bios/Makefile index ac2d520..3a9399a 100644 --- a/sw/bootloader/Makefile +++ b/sw/bios/Makefile @@ -1,39 +1,39 @@ CC=../cc65/bin/cl65 CFLAGS=-T -t none -I. --cpu "65C02" -test: CFLAGS=-T -t sim65c02 -I. LDFLAGS=-C link.ld -m $(NAME).map -SIM=sim65 -SIMARGS=-v -c -x 1000000 -NAME=bootloader +NAME=bios -TEST_BIN=test.bin BIN=$(NAME).bin HEX=$(NAME).hex +FPGA_IMG=../../hw/efinix_fpga/init_hex.mem +EFX_RUN=/home/byron/Software/efinity/2023.1/scripts/efx_run.py +EFX_PRJ=/home/byron/Projects/super6502/hw/efinix_fpga/super6502.xml + LISTS=lists TESTS=tests SRCS=$(wildcard *.s) $(wildcard *.c) -SRCS+=$(filter-out $(wildcard tests/*), $(wildcard **/*.s)) $(filter-out $(wildcard tests/*) $(wildcard filesystem/*), $(wildcard **/*.c)) +SRCS+=$(filter-out $(wildcard tests/*), $(wildcard **/*.s)) $(filter-out $(wildcard tests/*), $(wildcard **/*.c)) OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS))) OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS))) -TEST_SRCS=$(wildcard $(TESTS)/*.s) $(wildcard $(TESTS)/*.c) -TEST_OBJS+=$(patsubst %.s,%.o,$(filter %s,$(TEST_SRCS))) -TEST_OBJS+=$(patsubst %.c,%.o,$(filter %c,$(TEST_SRCS))) -TEST_OBJS+=$(filter-out boot.o,$(filter-out main.o,$(filter-out vectors.o,$(OBJS)))) - all: $(HEX) -test: $(TEST_BIN) - $(SIM) $(SIMARGS) $(TEST_BIN) - -$(TEST_BIN): $(OBJS) $(TEST_OBJS) - $(CC) $(CFLAGS) $(TEST_OBJS) -o $@ - $(HEX): $(BIN) objcopy --input-target=binary --output-target=verilog $(BIN) $(HEX) + cp boot2.bin ../fsdir + cmp $(HEX) $(FPGA_IMG); \ + RETVAL=$$?; \ + if [ $$RETVAL -eq 0 ]; then \ + echo "SAME"; \ + else \ + echo "NOT SAME"; \ + cp bios.hex ../../hw/efinix_fpga/init_hex.mem; \ + echo "Update ROM or rebuild FPGA image!"; \ + fi + $(BIN): $(OBJS) @@ -47,10 +47,8 @@ $(BIN): $(OBJS) $(LISTS): mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS)))) - mkdir $(LISTS)/$(sort $(dir $(TEST_SRCS))) .PHONY: clean clean: rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map - rm -rf $(TEST_OBJS) $(TEST_BIN) diff --git a/sw/bootloader/boot.s b/sw/bios/boot.s similarity index 100% rename from sw/bootloader/boot.s rename to sw/bios/boot.s diff --git a/sw/bios/boot2.s b/sw/bios/boot2.s new file mode 100644 index 0000000..8e6b5c8 --- /dev/null +++ b/sw/bios/boot2.s @@ -0,0 +1,161 @@ +.importzp sp, ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3, sreg, data_start + +.autoimport on + +.export fatbuf + +.feature string_escapes + +.MACPACK generic + +fatbuf = $A000 +filebuf = $B000 + +.segment "BOOTLOADER" + +sectors_per_cluster = $800D +reserved_sectors = $800E +fat_count = $8010 +sectors_per_fat = $8024 + +_start: + lda #str + jsr _cputs + + ; Read root directory entry into fatbuf + lda data_start + ldx data_start + 1 + jsr pushax + stz sreg + stz sreg+1 + jsr pusheax + lda #fatbuf + jsr pushax + lda #ptr1 + jsr _SD_readSingleBlock + + lda #fatbuf + jsr _SD_printBuf + + lda #$20 ; Start at first directory entry (first is a disk label) + sta ptr3 + lda #>fatbuf + sta ptr3 + 1 + ldy #$0b ; look for attributes +@1: lda (ptr3),y + + cmp #$0f ; if attribute is 0xf, this is a lfn + bne @2 ; if not an lfn, then try to read filename +@next: clc ; otherwise, go to the next entry (+0x20) + lda ptr3 + adc #$20 + sta ptr3 + bcc @4 + inc ptr3 + 1 +@4: lda #word_str + jsr pushax + lda ptr3 + ldx ptr3 + 1 + pha + phx + jsr pushax + phy + ldy #$4 + jsr _cprintf + ply + plx + stx ptr3 + 1 + pla + sta ptr3 + bra @1 + +@2: ldy #11 ; ignore the attributes. Write null to make a string + lda #$00 + sta (ptr3),y + lda ptr3 ; store address of the filename string on the stack + pha + ldx ptr3 + 1 + phx + jsr _cputs ; print out short filenames as we read them + lda #$0d + jsr _cputc + lda #$0a + jsr _cputc + lda #kernel_str + jsr pushax + plx ; then push the string we read earlier + pla + jsr _strcmp + bne @next ; if they are not equal then try next entry + lda #<_good ; print match if we found it + ldx #>_good + jsr _cputs ; otherwise continue on + + lda #word_str + jsr pushax + + lda ptr3 + pha + lda ptr3 + 1 + pha + + ldy #$1d ; load file size (256) + lda (ptr3),y + lsr ; divide by 2 to get file size (512) + jsr pusha0 + ldy #$4 + jsr _cprintf + + pla + sta ptr3 + 1 + pla + sta ptr3 + + ldy #$1b ; load high byte of low first cluster + lda (ptr3),y + tax + dey + lda (ptr3),y ; load low byte of low first cluster + + sec + sbc #$02 ; don't handle carry, assume low byte is not 0 or 1 + ldx data_start + 1 ; load x as high data start + asl ; multiply cluster num (minus 2) by 8 + asl + asl + clc + adc data_start ; add that to low data start + bcc @5 ; handle carry + inx +@5: stz sreg + stz sreg+1 + phx + pha + + jsr pusheax + lda #filebuf + jsr pushax + lda #ptr1 + jsr _SD_readSingleBlock + + lda #filebuf + jsr _SD_printBuf + +@end: bra @end + + + +str: .asciiz "boot2\r\n" +kernel_str: .asciiz "KERNEL O65" +_good: .asciiz "Found KERNEL\r\n" +word_str: .asciiz "Word Value: %x\r\n" \ No newline at end of file diff --git a/sw/bios/bootloader.s b/sw/bios/bootloader.s new file mode 100644 index 0000000..d928332 --- /dev/null +++ b/sw/bios/bootloader.s @@ -0,0 +1,195 @@ +.importzp sp, ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3, sreg +.exportzp data_start + +.autoimport on + +.feature string_escapes + +.MACPACK generic +.MACPACK longbranch + +_console_clear = $0 +_console_read_char = $2 +_console_write_char = $4 +_sd_readblock = $6 + +sectors_per_cluster = $800D +reserved_sectors = $800E +fat_count = $8010 +sectors_per_fat = $8024 + +buf = $8200 +addrh = $0000 +addrl = $0000 + +.zeropage + +data_start: .res 2 + + +.segment "BOOTSECTOR" + +_start: + jmp _main + +.byte "SUPR6502" + +_preamble: + +.res (11+_start-_preamble) + +_bpb: .res 60 + +_main: + lda #str + jsr _cputs + + lda fat_count + cmp #$2 + jne @fail + lda sectors_per_fat + asl + pha + lda sectors_per_fat + 1 + rol + tax + pla + adc reserved_sectors + bcc @a + inx +@a: sta data_start + stx data_start + 1 + jsr pushax + stz sreg + stz sreg+1 + jsr pusheax + lda #buf + jsr pushax + lda #ptr1 + jsr _SD_readSingleBlock + + lda #buf + jsr _SD_printBuf + + + lda #$20 ; Start at first directory entry (first is a disk label) + sta ptr3 + lda #>buf + sta ptr3 + 1 + ldy #$0b ; look for attributes +@1: lda (ptr3),y + + cmp #$0f ; if attribute is 0xf, this is a lfn + bne @2 ; if not an lfn, then try to read filename + clc ; otherwise, go to the next entry (+0x20) + lda ptr3 + adc #$20 + sta ptr3 + bra @1 + +@2: ldy #11 ; ignore the attributes. Write null to make a string + lda #$00 + sta (ptr3),y + lda ptr3 ; store address of the filename string on the stack + pha + ldx ptr3 + 1 + phx + lda #<_boot2_str ; load the string "BOOT2 BIN" + ldx #>_boot2_str + jsr pushax + plx ; then push the string we read earlier + pla + jsr _strcmp + bne @fail ; if they are not equal then fail + lda #<_good ; TODO: We should try the next entry + ldx #>_good + jsr _cputs ; otherwise continue on + + + ldy #$1b ; load the high byte of the low first cluster + lda (ptr3),y + tax + dey + lda (ptr3),y ; load the low byte of the low first cluster + + sec + sbc #$02 ; don't handle carry, assume low byte is not 0 or 1 + ldx data_start + 1 ; load x as high data start + asl ; multiply cluster num (minus 2) by 8 + asl + asl + clc + adc data_start ; add that to low data start + bcc @3 ; handle carry + inx +@3: stz sreg + stz sreg+1 + phx + pha + + + + jsr pusheax + lda #buf + jsr pushax + lda #ptr1 + jsr _SD_readSingleBlock + + stz sreg + stz sreg+1 + pla + plx + inc + jsr pusheax + lda #buf + inx + inx + jsr pushax + lda #ptr1 + jsr _SD_readSingleBlock + + + jmp buf + + bra @end + +; Now we have the cluster number of the bootloader (3) +; this means we need to read from address 00ef_e000 + ((3 -2) * 8 * 512) + +; 00eff000 is the address we want, which is efe000 + 4096 + + +@fail: lda #<_fail + ldx #>_fail + jsr _cputs + +@end: bra @end + +str: .asciiz "boot\r\n" +_boot2_str: .asciiz "BOOT2 BIN" +_fail: .asciiz "not bootloader\r\n" +_good: .asciiz "found bootloader!\r\n" +_cluster: .asciiz "cluster: %lx\r\n" +_addr: .asciiz "addr: %x\r\n" +_end: + +.res (440+_start-_end) + +.res 6 + +.res 16 +.res 16 +.res 16 +.res 16 + +.byte $55 +.byte $AA + diff --git a/sw/bootloader/devices/board_io.h b/sw/bios/devices/board_io.h similarity index 100% rename from sw/bootloader/devices/board_io.h rename to sw/bios/devices/board_io.h diff --git a/sw/bootloader/devices/board_io.s b/sw/bios/devices/board_io.s similarity index 100% rename from sw/bootloader/devices/board_io.s rename to sw/bios/devices/board_io.s diff --git a/sw/bootloader/devices/conio.s b/sw/bios/devices/conio.s similarity index 100% rename from sw/bootloader/devices/conio.s rename to sw/bios/devices/conio.s diff --git a/sw/bootloader/devices/interrupt.h b/sw/bios/devices/interrupt.h similarity index 100% rename from sw/bootloader/devices/interrupt.h rename to sw/bios/devices/interrupt.h diff --git a/sw/kernel/devices/interrupt.s b/sw/bios/devices/interrupt.s similarity index 61% rename from sw/kernel/devices/interrupt.s rename to sw/bios/devices/interrupt.s index f87f81d..862ae82 100644 --- a/sw/kernel/devices/interrupt.s +++ b/sw/bios/devices/interrupt.s @@ -7,9 +7,9 @@ ; Checks for a BRK instruction and returns from all valid interrupts. .import _handle_irq +.import _cputc, _clrscr .export _irq_int, _nmi_int -.export _irq_get_status, _irq_set_status .include "io.inc65" @@ -45,14 +45,56 @@ irq: PLA ; Restore accumulator contents ; --------------------------------------------------------------------------- ; BRK detected, stop -break: JMP break ; If BRK is detected, something very bad - ; has happened, so stop running +break: + pla + plx + jmp (bios_table,x) -_irq_get_status: - lda IRQ_STATUS - ldx #$00 - rts -_irq_set_status: - sta IRQ_STATUS - rts \ No newline at end of file +bios_table: + .addr _console_clear + .addr _console_read_char + .addr _console_write_char + + +_console_clear: + jsr _clrscr + rti + +_console_read_char: + ; not supported + rti + +_console_write_char: + jsr _cputc + rti + + + +; What functions do we need? +; UART +; clear +; write character +; read character +; DISK +; init (or should it just init on boot?) +; read sector into memory +; FS +; init (if disk init succeeds, should it always try?) +; find add + +; I think that is all we need for now? +; How do we call the functions? + +; we have to call `brk` to trigger the interrupt +; in any of the three registers we can have arguments +; or we could have them pushed to the stack, assuming +; the stack is in the same location +; Or you could pass a pointer which points to an array +; of arguments + +; for things like clear, read/write character, and init you don't +; need any arguments. + +; jump table index needs to be in x, but also needs to be a multiple +; of 2. diff --git a/sw/bootloader/devices/io.inc65 b/sw/bios/devices/io.inc65 similarity index 100% rename from sw/bootloader/devices/io.inc65 rename to sw/bios/devices/io.inc65 diff --git a/sw/bootloader/devices/sd_card.c b/sw/bios/devices/sd_card.c similarity index 87% rename from sw/bootloader/devices/sd_card.c rename to sw/bios/devices/sd_card.c index 22d4f54..8eaf708 100644 --- a/sw/bootloader/devices/sd_card.c +++ b/sw/bios/devices/sd_card.c @@ -276,56 +276,58 @@ void SD_sendStatus(uint8_t *res) token = 0x0X - Data error token = 0xFF - timeout *******************************************************************************/ -uint8_t SD_readSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *token) -{ - uint8_t res1, read; - uint16_t readAttempts; - uint16_t i; +// uint8_t SD_readSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *token) +// { +// uint8_t res1, read; +// uint16_t readAttempts; +// uint16_t i; - // set token to none - *token = 0xFF; +// // set token to none +// *token = 0xFF; - // assert chip select - spi_exchange(0xFF); - spi_select(0); - spi_exchange(0xFF); +// // assert chip select +// spi_exchange(0xFF); +// spi_select(0); +// spi_exchange(0xFF); - // send CMD17 - SD_command(CMD17, addr, CMD17_CRC); +// // send CMD17 +// SD_command(CMD17, addr, CMD17_CRC); - // read R1 - res1 = SD_readRes1(); +// // read R1 +// res1 = SD_readRes1(); - // if response received from card - if(res1 != 0xFF) - { - // wait for a response token (timeout = 100ms) - readAttempts = 0; - while(++readAttempts != SD_MAX_READ_ATTEMPTS) - if((read = spi_exchange(0xFF)) != 0xFF) break; +// // if response received from card +// if(res1 != 0xFF) +// { +// // wait for a response token (timeout = 100ms) +// readAttempts = 0; +// while(++readAttempts != SD_MAX_READ_ATTEMPTS) +// if((read = spi_exchange(0xFF)) != 0xFF) break; - // if response token is 0xFE - if(read == SD_START_TOKEN) - { - // read 512 byte block - for(i = 0; i < SD_BLOCK_LEN; i++) *buf++ = spi_exchange(0xFF); +// cprintf("read attempts: %d\r\n", readAttempts); - // read 16-bit CRC - spi_exchange(0xFF); - spi_exchange(0xFF); - } +// // if response token is 0xFE +// if(read == SD_START_TOKEN) +// { +// // read 512 byte block +// for(i = 0; i < SD_BLOCK_LEN; i++) *buf++ = spi_exchange(0xFF); - // set token to card response - *token = read; - } +// // read 16-bit CRC +// spi_exchange(0xFF); +// spi_exchange(0xFF); +// } - // deassert chip select - spi_exchange(0xFF); - spi_deselect(0); - spi_exchange(0xFF); +// // set token to card response +// *token = read; +// } - return res1; -} +// // deassert chip select +// spi_exchange(0xFF); +// spi_deselect(0); +// spi_exchange(0xFF); + +// return res1; +// } #define SD_MAX_WRITE_ATTEMPTS 3907 diff --git a/sw/bootloader/devices/sd_card.h b/sw/bios/devices/sd_card.h similarity index 100% rename from sw/bootloader/devices/sd_card.h rename to sw/bios/devices/sd_card.h diff --git a/sw/bootloader/devices/sd_card_asm.s b/sw/bios/devices/sd_card_asm.s similarity index 62% rename from sw/bootloader/devices/sd_card_asm.s rename to sw/bios/devices/sd_card_asm.s index 019286e..06e2142 100644 --- a/sw/bootloader/devices/sd_card_asm.s +++ b/sw/bios/devices/sd_card_asm.s @@ -6,8 +6,9 @@ .export _SD_readBytes .export _SD_powerUpSeq .export _res1_cmd +.export _SD_readSingleBlock -.importzp sp, ptr1 +.importzp sp, ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3 .autoimport on @@ -27,7 +28,7 @@ dey arg_loop: ; send ARG - lda (sp),y + lda (sp),y ; is this sending only 3? jsr _spi_exchange dey bpl arg_loop @@ -187,4 +188,116 @@ read: dex ; 2 bne @L1 ; 3 rts +.endproc + +; ;uint8_t SD_readSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *token) +.proc _SD_readSingleBlock: near + ; token address in a/x + ; buf address next on stack + ; sd address above that + + ; ptr2 = *token + sta ptr2 + stx ptr2 + 1 + + lda #$ff + sta (ptr2) + + ; ptr1 = *buf + jsr popptr1 + + ; 4 bytes on stack are addr + + ; Move addr down on the stack + lda sp + sta ptr3 + lda sp + 1 + sta ptr3 + 1 + + ; find a way to do this in a loop? + jsr decsp1 + ldy #$0 + lda (ptr3),y + sta (sp),y + iny + lda (ptr3),y + sta (sp),y + iny + lda (ptr3),y + sta (sp),y + iny + lda (ptr3),y + sta (sp),y + + lda #$ff + jsr _spi_exchange + lda #$00 ; this gets ignored anyway + jsr _spi_select + lda #$ff + jsr _spi_exchange + + ; push cmd17 + lda #$11 + ldy #$4 + sta (sp),y + + ; crc, 0 + lda #$00 + jsr _SD_command ; rely on command to teardown stack + + jsr _SD_readRes1 + + cmp #$ff ; if 0xFF then you failed + beq end + sta tmp3 ; tmp3 = read + + ; y = read_attempts + ldy #$0 +resp_loop: + lda #$ff + jsr _spi_exchange + sta tmp2 ; tmp2 = read + lda tmp2 + cmp #$ff + bne got_resp + iny + bne resp_loop + bra after_read + +got_resp: + ldx #$2 + ldy #$00 +load_loop: + lda #$ff + jsr _spi_exchange + sta (ptr1) + inc ptr1 + bne @2 + inc ptr1 + 1 +@2: dey + bne load_loop + ldy #$00 + dex + bne load_loop + lda #$ff + jsr _spi_exchange + lda #$ff + jsr _spi_exchange + +after_read: + lda tmp2 + sta (ptr2) + lda tmp3 + +end: + pha + lda #$ff + jsr _spi_exchange + lda #$00 ; this gets ignored anyway + jsr _spi_deselect + lda #$ff + jsr _spi_exchange + pla + rts + .endproc \ No newline at end of file diff --git a/sw/bios/devices/sd_print.c b/sw/bios/devices/sd_print.c new file mode 100644 index 0000000..7e3d305 --- /dev/null +++ b/sw/bios/devices/sd_print.c @@ -0,0 +1,26 @@ +#include + +#include "sd_print.h" +#include "sd_card.h" + + +void SD_printBuf(uint8_t *buf) +{ + uint8_t colCount = 0; + uint16_t i; + for(i = 0; i < SD_BLOCK_LEN; i++) + { + cprintf("%2x", *buf++); + if(colCount == 31) + { + cputs("\r\n"); + colCount = 0; + } + else + { + cputc(' '); + colCount++; + } + } + cputs("\r\n"); +} diff --git a/sw/bootloader/devices/sd_print.h b/sw/bios/devices/sd_print.h similarity index 100% rename from sw/bootloader/devices/sd_print.h rename to sw/bios/devices/sd_print.h diff --git a/sw/bootloader/devices/spi.h b/sw/bios/devices/spi.h similarity index 100% rename from sw/bootloader/devices/spi.h rename to sw/bios/devices/spi.h diff --git a/sw/bootloader/devices/spi.s b/sw/bios/devices/spi.s similarity index 100% rename from sw/bootloader/devices/spi.s rename to sw/bios/devices/spi.s diff --git a/sw/bootloader/devices/uart.h b/sw/bios/devices/uart.h similarity index 100% rename from sw/bootloader/devices/uart.h rename to sw/bios/devices/uart.h diff --git a/sw/bootloader/devices/uart.s b/sw/bios/devices/uart.s similarity index 100% rename from sw/bootloader/devices/uart.s rename to sw/bios/devices/uart.s diff --git a/sw/bootloader/irq.c b/sw/bios/irq.c similarity index 100% rename from sw/bootloader/irq.c rename to sw/bios/irq.c diff --git a/sw/bootloader/link.ld b/sw/bios/link.ld similarity index 72% rename from sw/bootloader/link.ld rename to sw/bios/link.ld index b1a51cf..59a987a 100644 --- a/sw/bootloader/link.ld +++ b/sw/bios/link.ld @@ -1,7 +1,10 @@ MEMORY { ZP: start = $0, size = $100, type = rw, define = yes; - SDRAM: start = $200, size = $7cf0, type = rw, define = yes; + KERNEL: start = $1000, size = $7000, type = rw, define = yes; + SDRAM: start = $9200, size = $4d00, type = rw, define = yes; + BOOTSECTOR: start = $8000, size = $200, type = rw, define = yes, file = "bootloader.bin"; + BOOTLOADER: start = $8200, size = $1000, type = rw, define = yes, file = "boot2.bin"; ROM: start = $F000, size = $1000, file = %O; } @@ -15,6 +18,8 @@ SEGMENTS { CODE: load = ROM, type = ro; RODATA: load = ROM, type = ro; VECTORS: load = ROM, type = ro, start = $FFFA; + BOOTSECTOR: load = BOOTSECTOR, type = rw, start = $8000; + BOOTLOADER: load = BOOTLOADER, type = rw; } FEATURES { diff --git a/sw/bios/main.c b/sw/bios/main.c new file mode 100644 index 0000000..27a701d --- /dev/null +++ b/sw/bios/main.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include + +#include "devices/board_io.h" +#include "devices/uart.h" +#include "devices/sd_card.h" +#include "devices/sd_print.h" + +#define KERNEL_LOAD_ADDR 0xD000 + +//uint8_t buf[512]; +uint8_t *buf = (uint8_t*)0x8000; + +int main() { + // array to hold responses + uint8_t res[5], token; + uint32_t addr = 0x00000000; + uint16_t i; + + cputs("Start\r\n"); + + // initialize sd card + if(SD_init() != SD_SUCCESS) + { + cputs("Error\r\n"); + } + else + { + cputs("Success\r\n"); + + + res[0] = SD_readSingleBlock(addr, buf, &token); + // if no error, print buffer + if((res[0] == 0x00) && (token == SD_START_TOKEN)) + SD_printBuf(buf); + //else if error token received, print + else if(!(token & 0xF0)) + { + cputs("Error\r\n"); + } else { + cprintf("bad token: %x\r\n", token); + } + + __asm__ ("jmp (%v)", buf); + } + + while(1) ; + +} diff --git a/sw/bootloader/vectors.s b/sw/bios/vectors.s similarity index 100% rename from sw/bootloader/vectors.s rename to sw/bios/vectors.s diff --git a/sw/bootloader/devices/interrupt.s b/sw/bootloader/devices/interrupt.s deleted file mode 100644 index 39e6b2a..0000000 --- a/sw/bootloader/devices/interrupt.s +++ /dev/null @@ -1,48 +0,0 @@ -; --------------------------------------------------------------------------- -; interrupt.s -; --------------------------------------------------------------------------- -; -; Interrupt handler. -; -; Checks for a BRK instruction and returns from all valid interrupts. - -.import _handle_irq - -.export _irq_int, _nmi_int - -.include "io.inc65" - -.segment "CODE" - -.PC02 ; Force 65C02 assembly mode - -; --------------------------------------------------------------------------- -; Non-maskable interrupt (NMI) service routine - -_nmi_int: RTI ; Return from all NMI interrupts - -; --------------------------------------------------------------------------- -; Maskable interrupt (IRQ) service routine - -_irq_int: PHX ; Save X register contents to stack - TSX ; Transfer stack pointer to X - PHA ; Save accumulator contents to stack - INX ; Increment X so it points to the status - INX ; register value saved on the stack - LDA $100,X ; Load status register contents - AND #$10 ; Isolate B status bit - BNE break ; If B = 1, BRK detected - -; --------------------------------------------------------------------------- -; IRQ detected, return - -irq: PLA ; Restore accumulator contents - PLX ; Restore X register contents - jsr _handle_irq ; Handle the IRQ - RTI ; Return from all IRQ interrupts - -; --------------------------------------------------------------------------- -; BRK detected, stop - -break: JMP break ; If BRK is detected, something very bad - ; has happened, so stop running diff --git a/sw/bootloader/devices/sd_print.c b/sw/bootloader/devices/sd_print.c deleted file mode 100644 index 2dcac25..0000000 --- a/sw/bootloader/devices/sd_print.c +++ /dev/null @@ -1,188 +0,0 @@ -#include - -#include "sd_print.h" -#include "sd_card.h" - -/* -void SD_printR1(uint8_t res) -{ - if(res == 0xFF) - { cputs("\tNo response\r\n"); return; } - if(res & 0x80) - { cputs("\tError: MSB = 1\r\n"); return; } - if(res == 0) - { cputs("\tCard Ready\r\n"); return; } - if(PARAM_ERROR(res)) - cputs("\tParameter Error\r\n"); - if(ADDR_ERROR(res)) - cputs("\tAddress Error\r\n"); - if(ERASE_SEQ_ERROR(res)) - cputs("\tErase Sequence Error\r\n"); - if(CRC_ERROR(res)) - cputs("\tCRC Error\r\n"); - if(ILLEGAL_CMD(res)) - cputs("\tIllegal Command\r\n"); - if(ERASE_RESET(res)) - cputs("\tErase Reset Error\r\n"); - if(IN_IDLE(res)) - cputs("\tIn Idle State\r\n"); -} -*/ - -/* -void SD_printR2(uint8_t *res) -{ - SD_printR1(res[0]); - - if(res[0] == 0xFF) return; - - if(res[1] == 0x00) - cputs("\tNo R2 Error\r\n"); - if(OUT_OF_RANGE(res[1])) - cputs("\tOut of Range\r\n"); - if(ERASE_PARAM(res[1])) - cputs("\tErase Parameter\r\n"); - if(WP_VIOLATION(res[1])) - cputs("\tWP Violation\r\n"); - if(CARD_ECC_FAILED(res[1])) - cputs("\tECC Failed\r\n"); - if(CC_ERROR(res[1])) - cputs("\tCC Error\r\n"); - if(ERROR(res[1])) - cputs("\tError\r\n"); - if(WP_ERASE_SKIP(res[1])) - cputs("\tWP Erase Skip\r\n"); - if(CARD_LOCKED(res[1])) - cputs("\tCard Locked\r\n"); -} -*/ - -/* -void SD_printR3(uint8_t *res) -{ - SD_printR1(res[0]); - - if(res[0] > 1) return; - - cputs("\tCard Power Up Status: "); - if(POWER_UP_STATUS(res[1])) - { - cputs("READY\r\n"); - cputs("\tCCS Status: "); - if(CCS_VAL(res[1])){ cputs("1\r\n"); } - else cputs("0\r\n"); - } - else - { - cputs("BUSY\r\n"); - } - - cputs("\tVDD Window: "); - if(VDD_2728(res[3])) cputs("2.7-2.8, "); - if(VDD_2829(res[2])) cputs("2.8-2.9, "); - if(VDD_2930(res[2])) cputs("2.9-3.0, "); - if(VDD_3031(res[2])) cputs("3.0-3.1, "); - if(VDD_3132(res[2])) cputs("3.1-3.2, "); - if(VDD_3233(res[2])) cputs("3.2-3.3, "); - if(VDD_3334(res[2])) cputs("3.3-3.4, "); - if(VDD_3435(res[2])) cputs("3.4-3.5, "); - if(VDD_3536(res[2])) cputs("3.5-3.6"); - cputs("\r\n"); -} -*/ - -/* -void SD_printR7(uint8_t *res) -{ - SD_printR1(res[0]); - - if(res[0] > 1) return; - - cputs("\tCommand Version: "); - cprintf("%x", CMD_VER(res[1])); - cputs("\r\n"); - - cputs("\tVoltage Accepted: "); - if(VOL_ACC(res[3]) == VOLTAGE_ACC_27_33) { - cputs("2.7-3.6V\r\n"); - } else if(VOL_ACC(res[3]) == VOLTAGE_ACC_LOW) { - cputs("LOW VOLTAGE\r\n"); - } else if(VOL_ACC(res[3]) == VOLTAGE_ACC_RES1) { - cputs("RESERVED\r\n"); - } else if(VOL_ACC(res[3]) == VOLTAGE_ACC_RES2) { - cputs("RESERVED\r\n"); - } else { - cputs("NOT DEFINED\r\n"); - } - - cputs("\tEcho: "); - cprintf("%x", res[4]); - cputs("\r\n"); -} -*/ - -/* -void SD_printCSD(uint8_t *buf) -{ - cputs("CSD:\r\n"); - - cputs("\tCSD Structure: "); - cprintf("%x", (buf[0] & 0b11000000) >> 6); - cputs("\r\n"); - - cputs("\tTAAC: "); - cprintf("%x", buf[1]); - cputs("\r\n"); - - cputs("\tNSAC: "); - cprintf("%x", buf[2]); - cputs("\r\n"); - - cputs("\tTRAN_SPEED: "); - cprintf("%x", buf[3]); - cputs("\r\n"); - - cputs("\tDevice Size: "); - cprintf("%x", buf[7] & 0b00111111); - cprintf("%x", buf[8]); - cprintf("%x", buf[9]); - cputs("\r\n"); -} -*/ - -void SD_printBuf(uint8_t *buf) -{ - uint8_t colCount = 0; - uint16_t i; - for(i = 0; i < SD_BLOCK_LEN; i++) - { - cprintf("%2x", *buf++); - if(colCount == 19) - { - cputs("\r\n"); - colCount = 0; - } - else - { - cputc(' '); - colCount++; - } - } - cputs("\r\n"); -} - -/* -void SD_printDataErrToken(uint8_t token) -{ - if(token & 0xF0) - cputs("\tNot Error token\r\n"); - if(SD_TOKEN_OOR(token)) - cputs("\tData out of range\r\n"); - if(SD_TOKEN_CECC(token)) - cputs("\tCard ECC failed\r\n"); - if(SD_TOKEN_CC(token)) - cputs("\tCC Error\r\n"); - if(SD_TOKEN_ERROR(token)) - cputs("\tError\r\n"); -} -*/ \ No newline at end of file diff --git a/sw/bootloader/filesystem/fat.c b/sw/bootloader/filesystem/fat.c deleted file mode 100644 index fbbd50f..0000000 --- a/sw/bootloader/filesystem/fat.c +++ /dev/null @@ -1,208 +0,0 @@ -#include -#include -#include - -#include "fat.h" -#include "devices/sd_card.h" - -uint8_t fat_buf[512]; - -static uint32_t fat_end_of_chain; - -static full_bpb_t bpb; - -static uint32_t data_region_start; - -void fat_init(){ - int i; - - sd_readblock(0, fat_buf); - - memcpy(&bpb, &fat_buf[11], sizeof(full_bpb_t)); - - sd_readblock(1, fat_buf); - sd_readblock(32, fat_buf); - - data_region_start = bpb.reserved_sectors + bpb.fat_count*bpb.sectors_per_fat_32; - - sd_readblock(bpb.reserved_sectors, fat_buf); - - //uncomment to view start of FAT - - /* - for (i = 0; i < FAT_CLUSTERS_PER_SECTOR; i++) { - cprintf("%lx ", ((uint32_t*)fat_buf)[i]); - } - cprintf("\n\n"); - */ - - fat_end_of_chain = ((uint32_t*)fat_buf)[1] & FAT_EOC_CLUSTERMASK; - cprintf("End of chain indicator: %lx\n", fat_end_of_chain); -} - - -// make sure you have enough space. -void fat_read_cluster(uint16_t cluster, uint8_t* buf) { - uint8_t i; - - for (i = 0; i < bpb.sectors_per_cluster; i++) { - sd_readblock(data_region_start + i + (cluster - 2) * 8, buf+i*bpb.bytes_per_sector); - } -} - -uint32_t fat_get_chain_value(uint16_t cluster) { - sd_readblock(bpb.reserved_sectors, fat_buf); - return ((uint32_t*)fat_buf)[cluster]; -} - -//the dentry is a double pointer because we need to increment it. -void fat_parse_vfat_filenamename(vfat_dentry_t** vfat_dentry, char* name, uint32_t cluster) { - uint8_t i; - uint8_t overflows; - uint8_t done; - char* shift_name; - uint8_t sequence_number = (*vfat_dentry)->sequence_number; - overflows = 0; - - for (;;){ - shift_name = name + 13*((sequence_number & FAT_LFN_ENTRY_MASK) - 1); - - done = 0; - for(i = 0; i < 5; i++) { - shift_name[i] = (*vfat_dentry)->filename0[i]; - if (!shift_name[i]) { - done = 1; - break; - } - } - - if (!done) { - for(i = 0; i < 6; i++) { - shift_name[i+5] = (*vfat_dentry)->filename1[i]; - if (!shift_name[i+5]) { - done = 1; - break; - } - } - } - - if (!done) { - for(i = 0; i < 2; i++) { - shift_name[i+11] = (*vfat_dentry)->filename2[i]; - if (!shift_name[i+11]) { - done = 1; - break; - } - } - } - - if ((sequence_number & FAT_LFN_ENTRY_MASK) == 1) { - break; - } else { - do { - (*vfat_dentry)++; - if ((uint8_t*)*vfat_dentry >= fat_buf + sizeof(fat_buf)) { - overflows++; - if (overflows == bpb.sectors_per_cluster) { - cprintf("Too many overflows, go back to fat!\n"); //TODO this - return; - } - sd_readblock(data_region_start + (cluster - 2) * 8 + overflows, fat_buf); - *vfat_dentry = (vfat_dentry_t*)fat_buf; - } - } while((*vfat_dentry)->sequence_number == 0xe5); - sequence_number = (*vfat_dentry)->sequence_number; - } - } - -} - -uint32_t fat_find_cluster_num(char* name, uint32_t cluster) { - vfat_dentry_t* vfat_dentry; - dos_dentry_t* dos_dentry; - char* vfat_name; - - cprintf("Looking for file %s\n", name); - - sd_readblock(data_region_start + (cluster - 2) * 8, fat_buf); - vfat_dentry = (vfat_dentry_t*)fat_buf; - - vfat_name = (char*)malloc(FAT_MAX_FILE_NAME); - - while(vfat_dentry->sequence_number == 0xe5) - vfat_dentry++; - - vfat_name[0] = '\0'; - - while(vfat_dentry->sequence_number) { - fat_parse_vfat_filenamename(&vfat_dentry, vfat_name, cluster); - cprintf("Parsed filename: %s\n", vfat_name); - - if (!strcmp(vfat_name, name)) { //TODO this is probably unsafe, use strncmp - cprintf("Found file %s\n", vfat_name); - break; - } else { - vfat_dentry += 2; - while(vfat_dentry->sequence_number == 0xe5) - vfat_dentry++; - } - } - - free(vfat_name); - - if (!vfat_dentry->sequence_number) { - cprintf("File not found.\n"); - return -1; - } - - dos_dentry = (dos_dentry_t*) vfat_dentry + 1; //dos entry follows last vfat entry - - cluster = ((uint32_t)dos_dentry->first_cluster_h << 16) + dos_dentry->first_cluster_l; - cprintf("Cluster: %ld\n", cluster); - - return cluster; -} - -uint16_t fat_parse_path_to_cluster(char* filename) { - //basically start at the root folder and search through it - int i; - int len; - uint8_t dirs = 0; - - char* spaced_filename; - char* fragment; - - uint32_t cluster = 2; //root chain is chain 2 - - if (filename[0] != '/') { - cprintf("Filename does not begin with '/'\n"); - return 0; - } - - filename++; - len = strlen(filename); - spaced_filename = (char*)malloc(len+1); //need to account for null byte - - for (i = 0; i <= len; i++) { - if (filename[i] == '/') { - spaced_filename[i] = '\0'; - dirs++; - } else { - spaced_filename[i] = filename[i]; - } - } - - fragment = spaced_filename; - - cprintf("Dirs: %d\n", dirs); - - for (i = 0; i <= dirs; i++) { - cprintf("Fragment: %s\n", fragment); - cluster = fat_find_cluster_num(fragment, cluster); - fragment = spaced_filename + strlen(fragment) + 1; - } - - free(spaced_filename); - - return cluster; -} diff --git a/sw/bootloader/filesystem/fat.h b/sw/bootloader/filesystem/fat.h deleted file mode 100644 index 2f7a640..0000000 --- a/sw/bootloader/filesystem/fat.h +++ /dev/null @@ -1,122 +0,0 @@ -#ifndef _FAT_H -#define _FAT_H - -#include - -extern uint8_t fat_buf[]; - -#define FAT_MAX_FILE_NAME 255 -#define FAT_CLUSTERS_PER_SECTOR 128 - -#define FAT_CLUSTERMASK 0x0fffffff -#define FAT_EOC_CLUSTERMASK 0x0ffffff8 - -#define FAT_LAST_LFN_MASK (1 << 6) -#define FAT_LFN_ENTRY_MASK 0x1f - -typedef struct { - uint16_t bytes_per_sector; - uint8_t sectors_per_cluster; - uint16_t reserved_sectors; - uint8_t fat_count; - uint16_t max_dir_entries; - uint16_t total_sector_count; - uint8_t media_descriptor; - uint16_t sectors_per_fat; -} dos_2_bpb_t; - -typedef struct { - dos_2_bpb_t bpb2; - uint16_t sectors_per_track; - uint16_t head_count; - uint32_t hidden_sector_count; - uint32_t logical_sector_count; - uint32_t sectors_per_fat; - uint16_t extended_flags; - uint16_t version; - uint32_t root_cluster; - uint16_t system_information; - uint16_t backup_boot_sector; - uint8_t reserved[12]; -} dos_3_bpb_t; - -typedef struct { - dos_3_bpb_t bpb3; - uint8_t drive_num; - uint8_t reserved; - uint8_t extended_signature; - uint32_t volume_id; - uint8_t partition_label[11]; - uint8_t filesystem_type[8]; -} ebpb_t; - -typedef struct { - uint16_t bytes_per_sector; - uint8_t sectors_per_cluster; - uint16_t reserved_sectors; - uint8_t fat_count; - uint16_t max_dir_entries; - uint16_t total_sector_count; - uint8_t media_descriptor; - uint16_t sectors_per_fat_16; - uint16_t sectors_per_track; - uint16_t head_count; - uint32_t hidden_sector_count; - uint32_t logical_sector_count; - uint32_t sectors_per_fat_32; - uint16_t extended_flags; - uint16_t version; - uint32_t root_cluster; - uint16_t system_information; - uint16_t backup_boot_sector; - uint8_t reserved[12]; - uint8_t drive_num; - uint8_t reserved2; - uint8_t extended_signature; - uint32_t volume_id; - uint8_t partition_label[11]; - uint8_t filesystem_type[8]; -} full_bpb_t; - -typedef struct { - uint32_t sig; - uint8_t reserved[480]; - uint32_t sig2; - uint32_t free_data_clusters; - uint32_t last_allocated_data_cluster; - uint32_t reserved2; - uint32_t sig3; -} fs_info_sector_t; - -typedef struct { - uint8_t sequence_number; - uint16_t filename0[5]; - uint8_t attributes; - uint8_t type; - uint8_t checksum; - uint16_t filename1[6]; - uint16_t reserved; - uint16_t filename2[2]; -} vfat_dentry_t; - -typedef struct { - uint8_t filename[8]; - uint8_t extension[3]; - uint8_t attributes; - uint8_t reserved; - uint8_t create_time_10ms; - uint32_t create_date; - uint16_t access_date; - uint16_t first_cluster_h; - uint32_t modify_cluster; - uint16_t first_cluster_l; - uint32_t file_size; -} dos_dentry_t; - -void fat_init(); - -uint16_t fat_parse_path_to_cluster(char* filename); -void fat_read_cluster(uint16_t cluster, uint8_t* buf); -uint32_t fat_get_chain_value(uint16_t cluster); - -#endif diff --git a/sw/bootloader/filesystem/o65.c b/sw/bootloader/filesystem/o65.c deleted file mode 100644 index 9e76dc0..0000000 --- a/sw/bootloader/filesystem/o65.c +++ /dev/null @@ -1,28 +0,0 @@ -#include - -#include "o65.h" - -void o65_print_option(o65_opt_t* opt) { - int i; - - cprintf("Option Length: %d\n", opt->olen); - cprintf("Option Type: %x ", opt->type); - - switch (opt->type) { - case O65_OPT_FILENAME: cprintf("Filename\n"); break; - case O65_OPT_OS: cprintf("OS\n"); break; - case O65_OPT_ASSEMBLER: cprintf("Assembler\n"); break; - case O65_OPT_AUTHOR: cprintf("Author\n"); break; - case O65_OPT_DATE: cprintf("Creation Date\n"); break; - default: cprintf("Invalid\n"); break; - } - - if (opt->type != O65_OPT_OS) { - for (i = 0; i < opt->olen - 2; i++) { - cprintf("%c", opt->data[i]); - } - } else { - cprintf("%x", opt->data[0]); - } - cprintf("\n\n"); -} diff --git a/sw/bootloader/filesystem/o65.h b/sw/bootloader/filesystem/o65.h deleted file mode 100644 index 719305c..0000000 --- a/sw/bootloader/filesystem/o65.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef _O65_H -#define _O65_H - -#include - -#define O65_NON_C64 0x0001 -#define O65_MAGIC_0 0x6f -#define O65_MAGIC_1 0x36 -#define O65_MAGIC_2 0x35 - -#define O65_OPT_FILENAME 0 -#define O65_OPT_OS 1 -#define O65_OPT_ASSEMBLER 2 -#define O65_OPT_AUTHOR 3 -#define O65_OPT_DATE 4 - -#define O65_OS_OSA65 1 -#define O65_OS_LUNIX 2 -#define O65_OS_CC65 3 -#define O65_OS_OPENCBM 4 -#define O65_OS_SUPER6502 5 - -typedef union { - struct { - int cpu : 1; - int reloc : 1; - int size : 1; - int obj : 1; - int simple : 1; - int chain : 1; - int bsszero : 1; - int cpu2 : 4; - int align : 2; - }; - uint16_t _mode; -} o65_mode_t; - -typedef struct { - uint16_t c64_marker; - uint8_t magic[3]; - uint8_t version; - - o65_mode_t mode; - - uint16_t tbase; - uint16_t tlen; - uint16_t dbase; - uint16_t dlen; - uint16_t bbase; - uint16_t blen; - uint16_t zbase; - uint16_t zlen; - uint16_t stack; - -} o65_header_t; - -typedef struct { - uint8_t olen; - uint8_t type; - uint8_t data[1]; //This is actually variable length -} o65_opt_t; - -void o65_print_option(o65_opt_t* opt); - -#endif diff --git a/sw/bootloader/main.c b/sw/bootloader/main.c deleted file mode 100644 index d22de3d..0000000 --- a/sw/bootloader/main.c +++ /dev/null @@ -1,81 +0,0 @@ -#include -#include -#include -#include - -#include "devices/board_io.h" -#include "devices/uart.h" -#include "devices/sd_card.h" -#include "devices/sd_print.h" -#include "filesystem/fat.h" - -#define KERNEL_LOAD_ADDR 0xD000 - -uint8_t buf[512]; - -int main() { - // array to hold responses - uint8_t res[5], token; - uint32_t addr = 0x00000000; - uint16_t i; - - cputs("Start\r\n"); - - // initialize sd card - if(SD_init() != SD_SUCCESS) - { - cputs("Error\r\n"); - } - else - { - cputs("Success\r\n"); - - // read sector 0 - cputs("\r\nReading sector: 0x"); - // ((uint8_t)(addr >> 24)); - // cprintf("%x", (uint8_t)(addr >> 16)); - // cprintf("%x", (uint8_t)(addr >> 8)); - // cprintf("%x", (uint8_t)addr); - res[0] = SD_readSingleBlock(addr, buf, &token); - cputs("\r\nResponse:\r\n"); - //SD_printR1(res[0]); - - // if no error, print buffer - if((res[0] == 0x00) && (token == SD_START_TOKEN)) - SD_printBuf(buf); - //else if error token received, print - else if(!(token & 0xF0)) - { - cputs("Error token:\r\n"); - //SD_printDataErrToken(token); - } - - // update address to 0x00000100 - // addr = 0x00000100; - - // // fill buffer with 0x55 - // for(i = 0; i < 512; i++) buf[i] = 0x55; - - // cputs("Writing 0x55 to sector: 0x"); - // cprintf("%x", (uint8_t)(addr >> 24)); - // cprintf("%x", (uint8_t)(addr >> 16)); - // cprintf("%x", (uint8_t)(addr >> 8)); - // cprintf("%x", (uint8_t)addr); - - // // write data to sector - // res[0] = SD_writeSingleBlock(addr, buf, &token); - - // cputs("\r\nResponse:\r\n"); - // //SD_printR1(res[0]); - - // // if no errors writing - // if(res[0] == 0x00) - // { - // if(token == SD_DATA_ACCEPTED) - // cputs("Write successful\r\n"); - // } - } - - while(1) ; - -} diff --git a/sw/bootloader/tests/test_main.c b/sw/bootloader/tests/test_main.c deleted file mode 100644 index 99e3dd8..0000000 --- a/sw/bootloader/tests/test_main.c +++ /dev/null @@ -1,89 +0,0 @@ -#include - -#include "devices/board_io.h" -#include "devices/uart.h" -#include "devices/interrupt.h" - -int main(void) -{ - int retval = 0; - - int i; - - printf("\nStarting tests...\n\n"); - - printf("Testing hex_set_8...\n"); - for (i = 0; i < 3; i++) { - if (hex_set_8(i+1, i)) { - printf("Failed to write to idx %d!\n", i); - retval++; - } - if (*(uint8_t*)0x7ff0+i != i+1) { - printf("Incorrect value at idx %d!\n", i); - retval++; - } - } - - if (!hex_set_8(0xab, 3)) { - printf("Writing to idx 3 should fail!\n"); - retval++; - } - printf("Done!\n\n"); - - printf("Testing hex_set_16...\n"); - if (hex_set_16(0xabcd)){ - printf("Failed to write!\n"); - } - if (*(uint16_t*)0x7ff0 != 0xabcd) { - printf("Incorrect value!\n", i); - retval++; - } - printf("Done!\n\n"); - - printf("Testing hex_set_24...\n"); - if (hex_set_24(0xabcdef)){ - printf("Failed to write!\n"); - } - if (*(uint16_t*)0x7ff0 != 0xcdef && *(uint8_t*)0x7ff2 != 0xab) { - printf("Incorrect value!\n", i); - retval++; - } - printf("Done!\n\n"); - - printf("Testing hex_enable...\n"); - hex_enable(0xa5); - if (*(uint8_t*)0x7ff3 != 0xa5) { - printf("Incorrect value!\n", i); - retval++; - } - printf("Done!\n\n"); - - printf("Testing uart_txb_block...\n"); - *(uint8_t*)0x7ff5 = 0; - uart_txb_block(0xa5); - if (*(uint8_t*)0x7ff4 != 0xa5) { - printf("Incorrect value!\n", i); - retval++; - } - printf("Done!\n\n"); - - printf("Testing uart_status...\n"); - *(uint8_t*)0x7ff5 = 0xa5; - if (uart_status() != 0xa5) { - printf("Incorrect value!\n", i); - retval++; - } - printf("Done!\n\n"); - - - printf("Testing irq_get_status...\n"); - *(uint8_t*)0x7fff = 0xa5; - if (irq_get_status() != 0xa5) { - printf("Incorrect value!\n", i); - retval++; - } - printf("Done!\n\n"); - - - return retval != 0; -} \ No newline at end of file diff --git a/sw/cc65 b/sw/cc65 index 9dc33cf..09e6c21 160000 --- a/sw/cc65 +++ b/sw/cc65 @@ -1 +1 @@ -Subproject commit 9dc33cff22a9cf7e5bdd67324694882bd322e53a +Subproject commit 09e6c21f820f7cebd08395d2f35c38d1d47c0ed5 diff --git a/sw/fsdir/hello.txt b/sw/fsdir/hello.txt deleted file mode 100644 index 270c611..0000000 --- a/sw/fsdir/hello.txt +++ /dev/null @@ -1 +0,0 @@ -hello, world! diff --git a/sw/kernel/Makefile b/sw/kernel/Makefile index ce9ac23..08e7a59 100644 --- a/sw/kernel/Makefile +++ b/sw/kernel/Makefile @@ -1,46 +1,27 @@ CC=../cc65/bin/cl65 -CFLAGS=-T -t super6502 -I. --cpu "65C02" -test: CFLAGS=-T -t sim65c02 -I. +LD=../cc65/bin/cl65 +CFLAGS=-T -t none -I. --cpu "65C02" LDFLAGS=-C link.ld -m $(NAME).map -SIM=../cc65/bin/sim65 -SIMARGS=-v -c -x 1000000 - -FSDIR=../fsdir NAME=kernel -TEST_BIN=test.bin -BIN=$(NAME).bin -HEX=$(NAME).hex +O65 = $(NAME).o65 + +FSDIR=../fsdir LISTS=lists -TESTS=tests SRCS=$(wildcard *.s) $(wildcard *.c) -SRCS+=$(filter-out $(wildcard tests/*), $(wildcard **/*.s)) $(filter-out $(wildcard tests/*), $(wildcard **/*.c)) +SRCS+=$(wildcard **/*.s) $(wildcard **/*.c) OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS))) OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS))) -TEST_SRCS=$(wildcard $(TESTS)/*.s) $(wildcard $(TESTS)/*.c) -TEST_OBJS+=$(patsubst %.s,%.o,$(filter %s,$(TEST_SRCS))) -TEST_OBJS+=$(patsubst %.c,%.o,$(filter %c,$(TEST_SRCS))) -TEST_OBJS+=$(filter-out boot.o,$(filter-out main.o,$(filter-out vectors.o,$(OBJS)))) +# Make sure the kernel linked to correct address, no relocation! +all: $(O65) + cp $(O65) $(FSDIR) -all: $(BIN) - cp $(BIN) $(FSDIR) - -test: $(TEST_BIN) - $(SIM) $(SIMARGS) $(TEST_BIN) - -$(TEST_BIN): $(OBJS) $(TEST_OBJS) - $(CC) $(CFLAGS) $(TEST_OBJS) -o $@ - -$(HEX): $(BIN) - objcopy --input-target=binary --output-target=ihex $(BIN) $(HEX) - - -$(BIN): $(OBJS) - $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@ +$(O65): $(OBJS) + $(LD) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@ %.o: %.c $(LISTS) $(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@ @@ -50,11 +31,7 @@ $(BIN): $(OBJS) $(LISTS): mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS)))) - mkdir $(LISTS)/$(sort $(dir $(TEST_SRCS))) .PHONY: clean clean: - rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map - rm -rf $(TEST_OBJS) $(TEST_BIN) - rm -rf $(FSDIR)/$(BIN) - + rm -rf $(OBJS) $(O65) $(LISTS) $(NAME).map \ No newline at end of file diff --git a/sw/kernel/boot.s b/sw/kernel/boot.s index a30963b..631fdd7 100644 --- a/sw/kernel/boot.s +++ b/sw/kernel/boot.s @@ -8,7 +8,7 @@ .import _main .export __STARTUP__ : absolute = 1 ; Mark as startup -.import __SDRAM_START__, __SDRAM_SIZE__ ; Linker generated +.import __STACKSTART__, __STACKSIZE__ ; Linker generated .import copydata, zerobss, initlib, donelib @@ -17,7 +17,7 @@ ; --------------------------------------------------------------------------- ; Place the startup code in a special segment -.segment "STARTUP" +.segment "STARTUP" ; --------------------------------------------------------------------------- ; A little light 6502 housekeeping @@ -29,10 +29,9 @@ _init: LDX #$FF ; Initialize stack pointer to $01FF ; --------------------------------------------------------------------------- ; Set cc65 argument stack pointer - ;LDA #<(__SDRAM_START__ + __SDRAM_SIZE__) - lda #<($200 + $7cf0) + LDA #<(__STACKSTART__ + __STACKSIZE__) STA sp - LDA #>($200 + $7cf0) + LDA #>(__STACKSTART__ + __STACKSIZE__) STA sp+1 ; --------------------------------------------------------------------------- diff --git a/sw/kernel/devices/board_io.h b/sw/kernel/devices/board_io.h deleted file mode 100644 index c55c7a5..0000000 --- a/sw/kernel/devices/board_io.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _BOARD_IO_H -#define _BOARD_IO_H - -#include - -uint8_t hex_set_8(uint8_t val, uint8_t idx); -uint8_t hex_set_16(uint16_t val); -uint8_t hex_set_24(uint32_t val); - -void hex_enable(uint8_t mask); - -uint8_t sw_read(); - -void led_set(uint8_t val); - -#endif \ No newline at end of file diff --git a/sw/kernel/devices/board_io.s b/sw/kernel/devices/board_io.s deleted file mode 100644 index 95656fe..0000000 --- a/sw/kernel/devices/board_io.s +++ /dev/null @@ -1,71 +0,0 @@ -.include "io.inc65" - -.importzp sp, sreg - -.export _hex_set_8 -.export _hex_set_16 -.export _hex_set_24 -.export _hex_enable -.export _sw_read -.export _led_set - -.autoimport on - -.code - -; @in A: idx Stack[0]: val -; @out A: 0 for success, 1 for failure. -; Sets one of the 3 pairs of hex digits. -_hex_set_8: - phx - cmp #$3 ; If idx >= 3 then fail - bcc @1 - plx - lda #$1 - rts -@1: tax ; Move idx into x - jsr popa ; put val into a - sta SEVEN_SEG,x ; write to val - lda #$0 - plx - rts - -; @in A/X: val -; @out A: 0 for success, 1 for failure -; Sets the low 2 pairs of hex digits -_hex_set_16: - sta SEVEN_SEG - stx SEVEN_SEG+1 - lda #$0 - rts - -; @in A/X/sreg: val -; @out A: 0 for success, 1 for failure -; Sets the 3 pairs of hex digits for a 24 bit value -_hex_set_24: - sta SEVEN_SEG - stx SEVEN_SEG+1 - lda sreg - sta SEVEN_SEG+2 - lda #$0 - rts - -; @in A: mask -; Set the mask for seven seg enables -_hex_enable: - sta SEVEN_SEG+3 - rts - -; @out A: The Value of the switches -; Reads the current values of the switches. -_sw_read: - lda SW - ldx #$0 - rts - -; @in A: val -; @out A: 0 for success, 1 for failure -; Sets the LEDs -_led_set: - sta LED - rts \ No newline at end of file diff --git a/sw/kernel/devices/conio.s b/sw/kernel/devices/conio.s index 30b4d6a..b7ebd46 100644 --- a/sw/kernel/devices/conio.s +++ b/sw/kernel/devices/conio.s @@ -6,7 +6,7 @@ .export _cputc .export gotoxy .export _clrscr -.export _cgetc +;.export _cgetc .autoimport on @@ -53,8 +53,8 @@ _clrscr: pla rts -_cgetc: -@2: lda _lastchar - beq @2 - stz _lastchar - rts \ No newline at end of file +;_cgetc: +;@2: lda _lastchar +; beq @2 +; stz _lastchar +; rts \ No newline at end of file diff --git a/sw/kernel/devices/interrupt.h b/sw/kernel/devices/interrupt.h deleted file mode 100644 index d0231aa..0000000 --- a/sw/kernel/devices/interrupt.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _INTERRUPT_H -#define _INTERRUPT_H - -#include - -#define BUTTON (1 << 0) -#define UART (1 << 1) - -void irq_int(); -void nmi_int(); - -uint8_t irq_get_status(); -void irq_set_status(uint8_t); - -#endif \ No newline at end of file diff --git a/sw/kernel/devices/io.inc65 b/sw/kernel/devices/io.inc65 index bad732c..42b0910 100644 --- a/sw/kernel/devices/io.inc65 +++ b/sw/kernel/devices/io.inc65 @@ -1,18 +1,13 @@ -SEVEN_SEG = $7ff0 - -UART = $7ff4 +UART = $efe6 UART_TXB = UART UART_RXB = UART UART_STATUS = UART + 1 -LED = $7ff6 +LED = $efff SW = LED -MM_CTRL = $7ff7 -MM_DATA = $7fe0 - -SD_ARG = $7ff8 -SD_CMD = $7ffc -SD_DATA = $7ffd - -IRQ_STATUS = $7fff +SPI_BAUD = $efd8 +SPI_INPUT = $efd9 +SPI_OUTPUT = $efda +SPI_CTRL = $efdb +SPI_STATUS = SPI_CTRL \ No newline at end of file diff --git a/sw/kernel/devices/mapper.h b/sw/kernel/devices/mapper.h deleted file mode 100644 index 8276b60..0000000 --- a/sw/kernel/devices/mapper.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _MAPPER_H -#define _MAPPER_H - -#include - -void mapper_enable(uint8_t en); - -uint8_t mapper_read(uint8_t addr); -void mapper_write(uint8_t data, uint8_t addr); - -#endif - diff --git a/sw/kernel/devices/mapper.s b/sw/kernel/devices/mapper.s deleted file mode 100644 index 2ed1bc0..0000000 --- a/sw/kernel/devices/mapper.s +++ /dev/null @@ -1,32 +0,0 @@ -.include "io.inc65" - -.importzp sp, sreg - -.export _mapper_enable -.export _mapper_read, _mapper_write - -.autoimport on - -.code - - -; void mapper_enable(uint8_t en) -_mapper_enable: - sta MM_CTRL - rts - -_mapper_read: - phx - tax - lda MM_DATA,x - ldx #$00 - rts - -_mapper_write: - phx - tax - jsr popa - sta MM_DATA,x - plx - rts - diff --git a/sw/kernel/devices/sd_card.c b/sw/kernel/devices/sd_card.c deleted file mode 100644 index 33bf986..0000000 --- a/sw/kernel/devices/sd_card.c +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include - -#include "devices/sd_card.h" - -void sd_init() { - uint32_t resp; - sd_card_command(0, 0); - - sd_card_command(0x000001aa, 8); - sd_card_resp(&resp); - //cprintf("CMD8: %lx\n", resp); - - sd_card_command(0, 55); - sd_card_command(0x40180000, 41); - sd_card_resp(&resp); - //cprintf("CMD41: %lx\n", resp); - - sd_card_command(0, 55); - sd_card_command(0x40180000, 41); - sd_card_resp(&resp); - //cprintf("CMD41: %lx\n", resp); - - sd_card_command(0, 2); - sd_card_resp(&resp); - //cprintf("CMD2: %lx\n", resp); -} - -uint16_t sd_get_rca() { - uint32_t resp; - - sd_card_command(0, 3); - resp = 0; - sd_card_resp(&resp); - - //cprintf("CMD3: %lx\n", resp); - - return resp >> 16; -} - -uint16_t sd_select_card(uint16_t rca) { - uint32_t resp; - - sd_card_command((uint32_t)rca << 16, 7); - sd_card_resp(&resp); - - return (uint16_t) resp; -} - -uint16_t sd_get_status(uint16_t rca) { - uint32_t resp; - - sd_card_command((uint32_t)rca << 16, 13); - sd_card_resp(&resp); - - return (uint16_t) resp; -} - -void sd_readblock(uint32_t addr, void* buf) { - uint32_t resp; - int i; - - sd_card_command(addr, 17); - sd_card_resp(&resp); - //cprintf("CMD17: %lx\n", resp); - - sd_card_wait_for_data(); - - //cprintf("Read data: \n"); - for (i = 0; i < 512; i++){ - ((uint8_t*)buf)[i] = sd_card_read_byte(); - } - - //cprintf("\n"); -} diff --git a/sw/kernel/devices/sd_card.h b/sw/kernel/devices/sd_card.h deleted file mode 100644 index 7e3cb00..0000000 --- a/sw/kernel/devices/sd_card.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _SD_CARD_H -#define _SD_CARD_H - -#include - -void sd_init(); -uint16_t sd_get_rca(); -uint16_t sd_select_card(uint16_t rca); -uint16_t sd_get_status(uint16_t rca); -void sd_readblock(uint32_t addr, void* buf); - -void sd_card_command(uint32_t arg, uint8_t cmd); - -void sd_card_resp(uint32_t* resp); -uint8_t sd_card_read_byte(); -void sd_card_wait_for_data(); - -#endif diff --git a/sw/kernel/devices/sd_card_asm.s b/sw/kernel/devices/sd_card_asm.s deleted file mode 100644 index fe4f4e2..0000000 --- a/sw/kernel/devices/sd_card_asm.s +++ /dev/null @@ -1,66 +0,0 @@ -.include "io.inc65" - -.importzp sp, sreg, ptr1 - -.export _sd_card_command -.export _sd_card_resp -.export _sd_card_read_byte -.export _sd_card_wait_for_data - -.autoimport on - -.code - -; Send sd card command. -; command is in A register, the args are on the stack -; I think the order is high byte first? -_sd_card_command: - pha - - jsr popeax - sta SD_ARG - stx SD_ARG+1 - lda sreg - sta SD_ARG+2 - lda sreg+1 - sta SD_ARG+3 - - pla - sta SD_CMD - rts - -; void sd_card_resp(uint32_t* resp); -_sd_card_resp: - phy - sta ptr1 ; store pointer - stx ptr1+1 -@1: lda SD_CMD ; wait for status flag - and #$01 - beq @1 - lda SD_ARG - ldy #$0 - sta (ptr1),y - lda SD_ARG+1 - iny - sta (ptr1),y - lda SD_ARG+2 - iny - sta (ptr1),y - lda SD_ARG+3 - iny - sta (ptr1),y - ply - rts - -_sd_card_read_byte: - lda SD_DATA - ldx #$00 - rts - -_sd_card_wait_for_data: - pha -@1: lda SD_CMD ; wait for status flag - and #$02 - beq @1 - pla - rts \ No newline at end of file diff --git a/sw/kernel/devices/uart.s b/sw/kernel/devices/uart.s index c852f7e..c99e0ad 100644 --- a/sw/kernel/devices/uart.s +++ b/sw/kernel/devices/uart.s @@ -19,8 +19,8 @@ _uart_txb: _uart_txb_block: pha sta UART_TXB ; Write value -@1: lda UART_STATUS ; Wait for status[0] to be 0 - bit #$01 +@1: lda UART_STATUS ; Wait for status[1] to be 0 + bit #$02 bne @1 pla rts diff --git a/sw/kernel/exec.c b/sw/kernel/exec.c deleted file mode 100644 index cbf1ccb..0000000 --- a/sw/kernel/exec.c +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include -#include - -#include "filesystem/fat.h" -#include "filesystem/o65.h" - -void exec(char* filename) { - o65_header_t* header; - o65_opt_t* o65_opt; - uint8_t* seg_ptr; - - uint8_t* code_base; - uint8_t* data_base; - uint16_t code_len; - uint16_t data_len; - - uint8_t (*exec)(void); - uint8_t ret; - - fat_read(filename, fat_buf); - - header = (o65_header_t*)fat_buf; - - if (header->c64_marker == O65_NON_C64 && - header->magic[0] == O65_MAGIC_0 && - header->magic[1] == O65_MAGIC_1 && - header->magic[2] == O65_MAGIC_2) { - - code_base = (uint8_t*)header->tbase; - data_base = (uint8_t*)header->dbase; - code_len = header->tlen; - data_len = header->dlen; - - - o65_opt = (o65_opt_t*)(fat_buf + sizeof(o65_header_t)); - while (o65_opt->olen) - { - o65_print_option(o65_opt); - o65_opt = (o65_opt_t*)((uint8_t*)o65_opt + o65_opt->olen); - } - - seg_ptr = (uint8_t*)o65_opt + 1; - - memcpy((uint8_t*)code_base, seg_ptr, code_len); - - seg_ptr+=code_len; - - memcpy((uint8_t*)data_base, seg_ptr, data_len); - - exec = (uint8_t (*)(void))code_base; - - ret = 0; - - //ret = (*exec)(); - - cprintf("ret: %x\n", ret); - - - } -} diff --git a/sw/kernel/exec.h b/sw/kernel/exec.h deleted file mode 100644 index 9ed3941..0000000 --- a/sw/kernel/exec.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _EXEC_H -#define _EXEC_H - -void exec(char* filename); - -#endif diff --git a/sw/kernel/filesystem/fat.c b/sw/kernel/filesystem/fat.c deleted file mode 100644 index cdcbdfd..0000000 --- a/sw/kernel/filesystem/fat.c +++ /dev/null @@ -1,246 +0,0 @@ -#include -#include -#include - -#include "fat.h" -#include "devices/sd_card.h" - -uint8_t fat_buf[512]; - -static uint32_t fat_end_of_chain; - -static full_bpb_t bpb; - -static uint32_t data_region_start; - -void fat_print_pbp_info(full_bpb_t* bpb){ - cprintf("Bytes per sector: %d\n", bpb->bytes_per_sector); - cprintf("Sectors per cluster: %d\n", bpb->sectors_per_cluster); - cprintf("Reserved Sectors: %d\n", bpb->reserved_sectors); - cprintf("Fat Count: %d\n", bpb->fat_count); - cprintf("Max Dir Entries: %d\n", bpb->max_dir_entries); - cprintf("Total Sector Count: %d\n", bpb->total_sector_count); - cprintf("Media Descriptor: 0x%x\n", bpb->media_descriptor); - cprintf("Sectors per Fat: %d\n", bpb->sectors_per_fat_16); - cprintf("\n"); - - cprintf("Sectors per track: %d\n", bpb->sectors_per_track); - cprintf("Head Count: %d\n", bpb->head_count); - cprintf("Hidden Sector Count: %ld\n", bpb->hidden_sector_count); - cprintf("Logical Sector Count: %ld\n", bpb->logical_sector_count); - cprintf("Sectors per Fat: %ld\n", bpb->sectors_per_fat_32); - cprintf("Extended Flags: 0x%x\n", bpb->extended_flags); - cprintf("Version: %d\n", bpb->version); - cprintf("Root Cluster: 0x%lx\n", bpb->root_cluster); - cprintf("System Information: 0x%x\n", bpb->system_information); - cprintf("Backup Boot Sector: 0x%x\n", bpb->backup_boot_sector); - cprintf("\n"); - - cprintf("Drive Number: %d\n", bpb->drive_num); - cprintf("Extended Signature: 0x%x\n", bpb->extended_signature); - cprintf("Volume ID: 0x%lx\n", bpb->volume_id); - cprintf("Partition Label: %.11s\n", &bpb->partition_label); - cprintf("Partition Label: %.8s\n", &bpb->filesystem_type); - cprintf("\n"); -} - -void fat_init(){ - //int i; - - sd_readblock(0, fat_buf); - - memcpy(&bpb, &fat_buf[11], sizeof(full_bpb_t)); - - sd_readblock(1, fat_buf); - sd_readblock(32, fat_buf); - - fat_print_pbp_info(&bpb); - - data_region_start = bpb.reserved_sectors + bpb.fat_count*bpb.sectors_per_fat_32; - - sd_readblock(bpb.reserved_sectors, fat_buf); - - //uncomment to view start of FAT - - /* - for (i = 0; i < FAT_CLUSTERS_PER_SECTOR; i++) { - cprintf("%lx ", ((uint32_t*)fat_buf)[i]); - } - cprintf("\n\n"); - */ - - fat_end_of_chain = ((uint32_t*)fat_buf)[1] & FAT_EOC_CLUSTERMASK; - cprintf("End of chain indicator: %lx\n", fat_end_of_chain); -} - -void fat_read(char* filename, void* buf) { - vfat_dentry_t* vfat_dentry; - dos_dentry_t* dos_dentry; - uint32_t cluster; - - (void)filename; //just ignore filename - - sd_readblock(data_region_start, buf); - - vfat_dentry = (vfat_dentry_t*)buf; - while(vfat_dentry->sequence_number == 0xe5) - vfat_dentry++; - - dos_dentry = (dos_dentry_t*)(vfat_dentry + 1); - - cluster = ((uint32_t)dos_dentry->first_cluster_h << 16) + dos_dentry->first_cluster_l; - - sd_readblock(data_region_start + (cluster - 2) * 8, buf); -} - -//the dentry is a double pointer because we need to increment it. -void fat_parse_vfat_filenamename(vfat_dentry_t** vfat_dentry, char* name, uint32_t cluster) { - uint8_t i; - uint8_t overflows; - uint8_t done; - char* shift_name; - uint8_t sequence_number = (*vfat_dentry)->sequence_number; - overflows = 0; - - for (;;){ - shift_name = name + 13*((sequence_number & FAT_LFN_ENTRY_MASK) - 1); - - done = 0; - for(i = 0; i < 5; i++) { - shift_name[i] = (*vfat_dentry)->filename0[i]; - if (!shift_name[i]) { - done = 1; - break; - } - } - - if (!done) { - for(i = 0; i < 6; i++) { - shift_name[i+5] = (*vfat_dentry)->filename1[i]; - if (!shift_name[i+5]) { - done = 1; - break; - } - } - } - - if (!done) { - for(i = 0; i < 2; i++) { - shift_name[i+11] = (*vfat_dentry)->filename2[i]; - if (!shift_name[i+11]) { - done = 1; - break; - } - } - } - - if ((sequence_number & FAT_LFN_ENTRY_MASK) == 1) { - break; - } else { - do { - (*vfat_dentry)++; - if ((uint8_t*)*vfat_dentry >= fat_buf + sizeof(fat_buf)) { - overflows++; - if (overflows == bpb.sectors_per_cluster) { - cprintf("Too many overflows, go back to fat!\n"); //TODO this - return; - } - sd_readblock(data_region_start + (cluster - 2) * 8 + overflows, fat_buf); - *vfat_dentry = (vfat_dentry_t*)fat_buf; - } - } while((*vfat_dentry)->sequence_number == 0xe5); - sequence_number = (*vfat_dentry)->sequence_number; - } - } - -} - -uint32_t fat_find_cluster_num(char* name, uint32_t cluster) { - vfat_dentry_t* vfat_dentry; - dos_dentry_t* dos_dentry; - char* vfat_name; - - cprintf("Looking for file %s\n", name); - - sd_readblock(data_region_start + (cluster - 2) * 8, fat_buf); - vfat_dentry = (vfat_dentry_t*)fat_buf; - - vfat_name = (char*)malloc(FAT_MAX_FILE_NAME); - - while(vfat_dentry->sequence_number == 0xe5) - vfat_dentry++; - - vfat_name[0] = '\0'; - - while(vfat_dentry->sequence_number) { - fat_parse_vfat_filenamename(&vfat_dentry, vfat_name, cluster); - cprintf("Parsed filename: %s\n", vfat_name); - - if (!strcmp(vfat_name, name)) { //TODO this is probably unsafe, use strncmp - cprintf("Found file %s\n", vfat_name); - break; - } else { - vfat_dentry += 2; - while(vfat_dentry->sequence_number == 0xe5) - vfat_dentry++; - } - } - - free(vfat_name); - - if (!vfat_dentry->sequence_number) { - cprintf("File not found.\n"); - return -1; - } - - dos_dentry = (dos_dentry_t*) vfat_dentry + 1; //dos entry follows last vfat entry - - cluster = ((uint32_t)dos_dentry->first_cluster_h << 16) + dos_dentry->first_cluster_l; - cprintf("Cluster: %ld\n", cluster); - - return cluster; -} - -uint16_t fat_parse_path_to_cluster(char* filename) { - //basically start at the root folder and search through it - int i; - int len; - uint8_t dirs = 0; - - char* spaced_filename; - char* fragment; - - uint32_t cluster = 2; //root chain is chain 2 - - if (filename[0] != '/') { - cprintf("Filename does not begin with '/'\n"); - return 0; - } - - filename++; - len = strlen(filename); - spaced_filename = (char*)malloc(len+1); //need to account for null byte - - for (i = 0; i <= len; i++) { - if (filename[i] == '/') { - spaced_filename[i] = '\0'; - dirs++; - } else { - spaced_filename[i] = filename[i]; - } - } - - fragment = spaced_filename; - - cprintf("Dirs: %d\n", dirs); - - for (i = 0; i <= dirs; i++) { - cprintf("Fragment: %s\n", fragment); - cluster = fat_find_cluster_num(fragment, cluster); - fragment = spaced_filename + strlen(fragment) + 1; - } - - free(spaced_filename); - - return cluster; -} diff --git a/sw/kernel/filesystem/fat.h b/sw/kernel/filesystem/fat.h deleted file mode 100644 index 9c26b5b..0000000 --- a/sw/kernel/filesystem/fat.h +++ /dev/null @@ -1,122 +0,0 @@ -#ifndef _FAT_H -#define _FAT_H - -#include - -extern uint8_t fat_buf[]; - -#define FAT_MAX_FILE_NAME 255 -#define FAT_CLUSTERS_PER_SECTOR 128 - -#define FAT_CLUSTERMASK 0x0fffffff -#define FAT_EOC_CLUSTERMASK 0x0ffffff8 - -#define FAT_LAST_LFN_MASK (1 << 6) -#define FAT_LFN_ENTRY_MASK 0x1f - -typedef struct { - uint16_t bytes_per_sector; - uint8_t sectors_per_cluster; - uint16_t reserved_sectors; - uint8_t fat_count; - uint16_t max_dir_entries; - uint16_t total_sector_count; - uint8_t media_descriptor; - uint16_t sectors_per_fat; -} dos_2_bpb_t; - -typedef struct { - dos_2_bpb_t bpb2; - uint16_t sectors_per_track; - uint16_t head_count; - uint32_t hidden_sector_count; - uint32_t logical_sector_count; - uint32_t sectors_per_fat; - uint16_t extended_flags; - uint16_t version; - uint32_t root_cluster; - uint16_t system_information; - uint16_t backup_boot_sector; - uint8_t reserved[12]; -} dos_3_bpb_t; - -typedef struct { - dos_3_bpb_t bpb3; - uint8_t drive_num; - uint8_t reserved; - uint8_t extended_signature; - uint32_t volume_id; - uint8_t partition_label[11]; - uint8_t filesystem_type[8]; -} ebpb_t; - -typedef struct { - uint16_t bytes_per_sector; - uint8_t sectors_per_cluster; - uint16_t reserved_sectors; - uint8_t fat_count; - uint16_t max_dir_entries; - uint16_t total_sector_count; - uint8_t media_descriptor; - uint16_t sectors_per_fat_16; - uint16_t sectors_per_track; - uint16_t head_count; - uint32_t hidden_sector_count; - uint32_t logical_sector_count; - uint32_t sectors_per_fat_32; - uint16_t extended_flags; - uint16_t version; - uint32_t root_cluster; - uint16_t system_information; - uint16_t backup_boot_sector; - uint8_t reserved[12]; - uint8_t drive_num; - uint8_t reserved2; - uint8_t extended_signature; - uint32_t volume_id; - uint8_t partition_label[11]; - uint8_t filesystem_type[8]; -} full_bpb_t; - -typedef struct { - uint32_t sig; - uint8_t reserved[480]; - uint32_t sig2; - uint32_t free_data_clusters; - uint32_t last_allocated_data_cluster; - uint32_t reserved2; - uint32_t sig3; -} fs_info_sector_t; - -typedef struct { - uint8_t sequence_number; - uint16_t filename0[5]; - uint8_t attributes; - uint8_t type; - uint8_t checksum; - uint16_t filename1[6]; - uint16_t reserved; - uint16_t filename2[2]; -} vfat_dentry_t; - -typedef struct { - uint8_t filename[8]; - uint8_t extension[3]; - uint8_t attributes; - uint8_t reserved; - uint8_t create_time_10ms; - uint32_t create_date; - uint16_t access_date; - uint16_t first_cluster_h; - uint32_t modify_cluster; - uint16_t first_cluster_l; - uint32_t file_size; -} dos_dentry_t; - -void fat_print_pbp_info(full_bpb_t* bpb); -void fat_init(); -void fat_read(char* filename, void* buf); - -uint16_t fat_parse_path_to_cluster(char* filename); - -#endif diff --git a/sw/kernel/filesystem/o65.c b/sw/kernel/filesystem/o65.c deleted file mode 100644 index 9e76dc0..0000000 --- a/sw/kernel/filesystem/o65.c +++ /dev/null @@ -1,28 +0,0 @@ -#include - -#include "o65.h" - -void o65_print_option(o65_opt_t* opt) { - int i; - - cprintf("Option Length: %d\n", opt->olen); - cprintf("Option Type: %x ", opt->type); - - switch (opt->type) { - case O65_OPT_FILENAME: cprintf("Filename\n"); break; - case O65_OPT_OS: cprintf("OS\n"); break; - case O65_OPT_ASSEMBLER: cprintf("Assembler\n"); break; - case O65_OPT_AUTHOR: cprintf("Author\n"); break; - case O65_OPT_DATE: cprintf("Creation Date\n"); break; - default: cprintf("Invalid\n"); break; - } - - if (opt->type != O65_OPT_OS) { - for (i = 0; i < opt->olen - 2; i++) { - cprintf("%c", opt->data[i]); - } - } else { - cprintf("%x", opt->data[0]); - } - cprintf("\n\n"); -} diff --git a/sw/kernel/filesystem/o65.h b/sw/kernel/filesystem/o65.h deleted file mode 100644 index 719305c..0000000 --- a/sw/kernel/filesystem/o65.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef _O65_H -#define _O65_H - -#include - -#define O65_NON_C64 0x0001 -#define O65_MAGIC_0 0x6f -#define O65_MAGIC_1 0x36 -#define O65_MAGIC_2 0x35 - -#define O65_OPT_FILENAME 0 -#define O65_OPT_OS 1 -#define O65_OPT_ASSEMBLER 2 -#define O65_OPT_AUTHOR 3 -#define O65_OPT_DATE 4 - -#define O65_OS_OSA65 1 -#define O65_OS_LUNIX 2 -#define O65_OS_CC65 3 -#define O65_OS_OPENCBM 4 -#define O65_OS_SUPER6502 5 - -typedef union { - struct { - int cpu : 1; - int reloc : 1; - int size : 1; - int obj : 1; - int simple : 1; - int chain : 1; - int bsszero : 1; - int cpu2 : 4; - int align : 2; - }; - uint16_t _mode; -} o65_mode_t; - -typedef struct { - uint16_t c64_marker; - uint8_t magic[3]; - uint8_t version; - - o65_mode_t mode; - - uint16_t tbase; - uint16_t tlen; - uint16_t dbase; - uint16_t dlen; - uint16_t bbase; - uint16_t blen; - uint16_t zbase; - uint16_t zlen; - uint16_t stack; - -} o65_header_t; - -typedef struct { - uint8_t olen; - uint8_t type; - uint8_t data[1]; //This is actually variable length -} o65_opt_t; - -void o65_print_option(o65_opt_t* opt); - -#endif diff --git a/sw/kernel/irq.c b/sw/kernel/irq.c deleted file mode 100644 index 4d2c0d8..0000000 --- a/sw/kernel/irq.c +++ /dev/null @@ -1,24 +0,0 @@ - -#include -#include - -#include "devices/interrupt.h" -#include "devices/uart.h" - -char lastchar; - - -void handle_irq() { - uint8_t status; - - status = irq_get_status(); - - if (status & BUTTON) { - cputs("Button Interrupt!\n"); - irq_set_status(status & ~BUTTON); - } - if (status & UART) { - lastchar = uart_rxb(); - irq_set_status(status & ~UART); - } -} \ No newline at end of file diff --git a/sw/kernel/kernel.c b/sw/kernel/kernel.c new file mode 100644 index 0000000..edefc3b --- /dev/null +++ b/sw/kernel/kernel.c @@ -0,0 +1,9 @@ +#include + +int main() { + cprintf("Hello, world!\r\n"); + + while(1); + + return 0; +} \ No newline at end of file diff --git a/sw/kernel/link.ld b/sw/kernel/link.ld index d0f634b..a7e01bb 100644 --- a/sw/kernel/link.ld +++ b/sw/kernel/link.ld @@ -1,20 +1,33 @@ MEMORY { - ZP: start = $0, size = $100, type = rw, define = yes; - SDRAM: start = $200, size = $7cf0, type = rw, define = yes; - ROM: start = $D000, size = $3000, type = rw, define = yes, file = %O; + ZP: start = $0, size = $100, type = rw, define = yes; + STACK: start = $200, size = $E00, type = rw, define = yes; + KERNEL: start = $1000, size = $7000, type = rw, define = yes, file = %O; + USER: start = $8000, size = $6000, type = rw, define = yes; + IO: start = $E000, size = $1000, type = rw, define = yes; + ROM: start = $f000, size = $1000, type = rw, define = yes; #rw for vectors } 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; + ZEROPAGE: load = ZP, type = zp, define = yes; + STARTUP: load = KERNEL, type = ro; + ONCE: load = KERNEL, type = ro, optional = yes; + CODE: load = KERNEL, type = ro; + RODATA: load = KERNEL, type = ro; + DATA: load = KERNEL, type = rw, define = yes; + BSS: load = KERNEL, type = rw, define = yes; + HEAP: load = KERNEL, type = rw, define = yes, optional = yes; +} + +FILES +{ + %O: format = o65; +} + +FORMATS +{ + o65: os = super, version = 0, type = small, + export = _init; } FEATURES { @@ -29,7 +42,7 @@ FEATURES { } SYMBOLS { - # Define the stack size for the application - __STACKSIZE__: value = $0200, type = weak; - __STACKSTART__: type = weak, value = $0800; # 2k stack + __STACKSIZE__: value = $0E00, type = weak; + __STACKSTART__: type = weak, value = $0800; } + diff --git a/sw/kernel/main.c b/sw/kernel/main.c deleted file mode 100644 index 1039619..0000000 --- a/sw/kernel/main.c +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include -#include -#include - -#include "devices/board_io.h" -#include "devices/uart.h" -#include "devices/mapper.h" -#include "devices/sd_card.h" -#include "filesystem/fat.h" -#include "exec.h" - -uint8_t buf[512]; - -int main() { - uint16_t rca; - char* filename; - - clrscr(); - cprintf("Hello, world! Modified\n"); - - sd_init(); - - rca = sd_get_rca(); - cprintf("rca: %x\n", rca); - - sd_select_card(rca); - - fat_init(); - - filename = (char*)malloc(FAT_MAX_FILE_NAME); - - for(;;) { - cprintf("Filename: "); - cscanf("%s", filename); - cprintf("\n"); - fat_parse_path_to_cluster(filename); - } - - //exec("/test.o65"); - - cprintf("Done!\n"); - - return 0; -} diff --git a/sw/kernel/tests/test_main.c b/sw/kernel/tests/test_main.c deleted file mode 100644 index 99e3dd8..0000000 --- a/sw/kernel/tests/test_main.c +++ /dev/null @@ -1,89 +0,0 @@ -#include - -#include "devices/board_io.h" -#include "devices/uart.h" -#include "devices/interrupt.h" - -int main(void) -{ - int retval = 0; - - int i; - - printf("\nStarting tests...\n\n"); - - printf("Testing hex_set_8...\n"); - for (i = 0; i < 3; i++) { - if (hex_set_8(i+1, i)) { - printf("Failed to write to idx %d!\n", i); - retval++; - } - if (*(uint8_t*)0x7ff0+i != i+1) { - printf("Incorrect value at idx %d!\n", i); - retval++; - } - } - - if (!hex_set_8(0xab, 3)) { - printf("Writing to idx 3 should fail!\n"); - retval++; - } - printf("Done!\n\n"); - - printf("Testing hex_set_16...\n"); - if (hex_set_16(0xabcd)){ - printf("Failed to write!\n"); - } - if (*(uint16_t*)0x7ff0 != 0xabcd) { - printf("Incorrect value!\n", i); - retval++; - } - printf("Done!\n\n"); - - printf("Testing hex_set_24...\n"); - if (hex_set_24(0xabcdef)){ - printf("Failed to write!\n"); - } - if (*(uint16_t*)0x7ff0 != 0xcdef && *(uint8_t*)0x7ff2 != 0xab) { - printf("Incorrect value!\n", i); - retval++; - } - printf("Done!\n\n"); - - printf("Testing hex_enable...\n"); - hex_enable(0xa5); - if (*(uint8_t*)0x7ff3 != 0xa5) { - printf("Incorrect value!\n", i); - retval++; - } - printf("Done!\n\n"); - - printf("Testing uart_txb_block...\n"); - *(uint8_t*)0x7ff5 = 0; - uart_txb_block(0xa5); - if (*(uint8_t*)0x7ff4 != 0xa5) { - printf("Incorrect value!\n", i); - retval++; - } - printf("Done!\n\n"); - - printf("Testing uart_status...\n"); - *(uint8_t*)0x7ff5 = 0xa5; - if (uart_status() != 0xa5) { - printf("Incorrect value!\n", i); - retval++; - } - printf("Done!\n\n"); - - - printf("Testing irq_get_status...\n"); - *(uint8_t*)0x7fff = 0xa5; - if (irq_get_status() != 0xa5) { - printf("Incorrect value!\n", i); - retval++; - } - printf("Done!\n\n"); - - - return retval != 0; -} \ No newline at end of file diff --git a/sw/kernel/vectors.s b/sw/kernel/vectors.s deleted file mode 100644 index 81ae6e0..0000000 --- a/sw/kernel/vectors.s +++ /dev/null @@ -1,14 +0,0 @@ -; --------------------------------------------------------------------------- -; 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/script/copy_files.sh b/sw/script/copy_files.sh index 17bc144..4ff38da 100644 --- a/sw/script/copy_files.sh +++ b/sw/script/copy_files.sh @@ -1,8 +1,8 @@ DEVICE=/dev/mmcblk0 TMPMOUNT=/tmp/sd -FSDIR=fsdir +FSDIR=../fsdir -V= +V=-v echo "$(tput bold setaf 11)Mounting Device$(tput sgr 0)" mkdir $V -p $TMPMOUNT @@ -16,4 +16,4 @@ echo echo "$(tput bold setaf 11)Unmounting Device$(tput sgr 0)" sudo umount $V $DEVICE rmdir $V $TMPMOUNT -echo \ No newline at end of file +echo diff --git a/sw/script/format_disk.sh b/sw/script/format_disk.sh index 99b82a6..af66e59 100644 --- a/sw/script/format_disk.sh +++ b/sw/script/format_disk.sh @@ -1,23 +1,20 @@ #!/bin/bash -BOOTLOADER=bootloader/bootloader.bin +BOOTLOADER=../bios/bootloader.bin DEVICE=/dev/mmcblk0 TMPBOOTSECT=/tmp/bootsect TMPMOUNT=/tmp/sd -V= -STATUS="status=none" +V=-v +# STATUS="status=none" +STATUS= echo "$(tput bold setaf 11)Creating Filesystem$(tput sgr 0)" -sudo mkfs.vfat -F32 $DEVICE -n SUPER6502 $V +sudo mkfs.vfat -I -F32 $DEVICE -n SUPER6502 $V echo echo "$(tput bold setaf 11)Modifying Boot Sector$(tput sgr 0)" -sudo dd if=$DEVICE of=$TMPBOOTSECT bs=512 count=1 $STATUS -sudo dd conv=notrunc if=$BOOTLOADER of=$DEVICE bs=512 skip=0 count=1 $STATUS -sudo dd conv=notrunc if=$TMPBOOTSECT of=$DEVICE bs=1 skip=0 count=90 iflag=skip_bytes,count_bytes $STATUS -sudo dd conv=notrunc if=$BOOTLOADER of=$DEVICE bs=1 skip=0 count=3 iflag=skip_bytes,count_bytes $STATUS -echo +sudo dd if=$BOOTLOADER of=$DEVICE bs=1 count=11 $STATUS +sudo dd if=$BOOTLOADER of=$DEVICE bs=1 count=380 seek=71 skip=71 $STATUS echo "$(tput bold setaf 10)Done!$(tput sgr 0)" - diff --git a/sw/script/o65dump.py b/sw/script/o65dump.py new file mode 100755 index 0000000..637de94 --- /dev/null +++ b/sw/script/o65dump.py @@ -0,0 +1,101 @@ +#!/usr/bin/python + +import sys +import io + +class O65(): + + header: dict[str, int] = {} + options: list[(int, int, bytes)] = [] + text: bytes + data: bytes + undef_ref_cnt: int + text_reloc: list[(int, int, int)] = [] + data_reloc: list[(int, int, int)] = [] + exports: list[(str, int, int)] = [] + + def __init__(self, filename: str) -> None: + with open(filename, "rb") as _file: + self.header["no_c64"] = int.from_bytes(_file.read(2)) + self.header["magic"] = int.from_bytes(_file.read(3)) + self.header["version"] = int.from_bytes(_file.read(1)) + self.header["mode"] = int.from_bytes(_file.read(2), byteorder="little") + self.header["tbase"] = int.from_bytes(_file.read(2), byteorder="little") + self.header["tlen"] = int.from_bytes(_file.read(2), byteorder="little") + self.header["dbase"] = int.from_bytes(_file.read(2), byteorder="little") + self.header["dlen"] = int.from_bytes(_file.read(2), byteorder="little") + self.header["bbase"] = int.from_bytes(_file.read(2), byteorder="little") + self.header["blen"] = int.from_bytes(_file.read(2), byteorder="little") + self.header["zbase"] = int.from_bytes(_file.read(2), byteorder="little") + self.header["zlen"] = int.from_bytes(_file.read(2), byteorder="little") + self.header["stack"] = int.from_bytes(_file.read(2), byteorder="little") + + olen = int.from_bytes(_file.read(1)) + while olen != 0: + otype = int.from_bytes(_file.read(1)) + obytes = _file.read(olen - 2) + self.options.append((olen, otype, obytes)) + olen = int.from_bytes(_file.read(1)) + + self.text = _file.read(self.header["tlen"]) + self.data = _file.read(self.header["dlen"]) + + self.undef_ref_cnt = _file.read(2) + + self.text_reloc = self._parse_reloc(_file) + self.data_reloc = self._parse_reloc(_file) + + export_count = int.from_bytes(_file.read(2), byteorder="little") + for _ in range(export_count): + name: bytearray = bytearray() + data = 0 + while True: + data = _file.read(1) + if data != b"\x00": + name.extend(data) + else: + break + segment = int.from_bytes(_file.read(1)) + value = int.from_bytes(_file.read(2), byteorder="little") + self.exports.append((name.decode(), segment, value)) + + def _parse_reloc(self, fd: io.BufferedReader) -> list[(int, int, int)]: + reloc: list[(int, int, int)] = [] + offset = fd.read(1) + while offset != b'\x00': + offset_val = 0 + while offset == b'\xff': + offset = fd.read(1) + offset_val += int.from_bytes(offset) - 1 + offset_val += int.from_bytes(offset) + typebyte = int.from_bytes(fd.read(1)) + lobyte = None + if typebyte & 0x40: + lobyte = int.from_bytes(fd.read(1)) + reloc.append((offset_val, typebyte, lobyte)) + offset = fd.read(1) + return reloc + + +def main() -> None: + if len(sys.argv) < 2: + print("Please supply a filename") + return + filename = sys.argv[1] + print(filename) + o65 = O65(filename) + for item, value in o65.header.items(): + print(f"{item}:\t{value:x}") + + for option in o65.options: + print(f"Type: {option[1]}, Data: {option[2]}") + + print(f"Text size: {len(o65.text)}") + print(f"Data size: {len(o65.data)}") + + for item in o65.exports: + print(f"Name: {item[0]} Addr: {item[2]:#x}") + +if __name__ == "__main__": + main() + diff --git a/sw/test_exec/Makefile b/sw/test_exec/Makefile index a02cbfe..5a26b91 100644 --- a/sw/test_exec/Makefile +++ b/sw/test_exec/Makefile @@ -1,4 +1,4 @@ -CC=cl65 +CC=../cc65/bin/cl65 CFLAGS=-T -t super6502 -I. --cpu "65C02" test: CFLAGS=-T -t sim65c02 -I. LDFLAGS=-C link.ld -m $(NAME).map diff --git a/sw/test_exec/link.ld b/sw/test_exec/link.ld index ade4e99..c1c36c8 100644 --- a/sw/test_exec/link.ld +++ b/sw/test_exec/link.ld @@ -10,13 +10,13 @@ FILES { SEGMENTS { ZEROPAGE: load = ZP, type = zp, define = yes; - DATA: load = SDRAM, type = rw, define = yes, run = SDRAM; - BSS: load = SDRAM, type = bss, define = yes; - HEAP: load = SDRAM, type = bss, optional = yes; STARTUP: load = SDRAM, type = ro; ONCE: load = SDRAM, type = ro, optional = yes; CODE: load = SDRAM, type = ro; RODATA: load = SDRAM, type = ro; + DATA: load = SDRAM, type = rw, define = yes, run = SDRAM; + BSS: load = SDRAM, type = bss, define = yes; + HEAP: load = SDRAM, type = bss, optional = yes; } FEATURES {