Merge branch 'bios' into 'master'
Link bootloader with bios to get access to symbols See merge request bslathi19/super6502!18
This commit is contained in:
@@ -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
|
||||
@@ -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": [
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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 (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<efx:project name="super6502" description="" last_change_date="Sun July 23 2023 16:23:00" location="/home/byron/Projects/super6502/hw/efinix_fpga" sw_version="2023.1.150" last_run_state="pass" last_run_tool="efx_pgm" last_run_flow="bitstream" config_result_in_sync="true" design_ood="sync" place_ood="sync" route_ood="sync" xmlns:efx="http://www.efinixinc.com/enf_proj" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.efinixinc.com/enf_proj enf_proj.xsd">
|
||||
<efx:project name="super6502" description="" last_change_date="Mon August 21 2023 19:23:14" location="/home/byron/Projects/super6502/hw/efinix_fpga" sw_version="2023.1.150" last_run_state="pass" last_run_tool="efx_pgm" last_run_flow="bitstream" config_result_in_sync="true" design_ood="sync" place_ood="sync" route_ood="sync" xmlns:efx="http://www.efinixinc.com/enf_proj" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.efinixinc.com/enf_proj enf_proj.xsd">
|
||||
<efx:device_info>
|
||||
<efx:family name="Trion"/>
|
||||
<efx:device name="T20F256"/>
|
||||
@@ -100,7 +100,7 @@
|
||||
</efx:bitstream_generation>
|
||||
<efx:debugger>
|
||||
<efx:param name="work_dir" value="work_dbg" value_type="e_string"/>
|
||||
<efx:param name="auto_instantiation" value="on" value_type="e_bool"/>
|
||||
<efx:param name="auto_instantiation" value="off" value_type="e_bool"/>
|
||||
<efx:param name="profile" value="debug_profile.wizard.json" value_type="e_string"/>
|
||||
</efx:debugger>
|
||||
</efx:project>
|
||||
|
||||
@@ -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)
|
||||
|
||||
161
sw/bios/boot2.s
Normal file
161
sw/bios/boot2.s
Normal file
@@ -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
|
||||
ldx #>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
|
||||
ldx #>fatbuf
|
||||
jsr pushax
|
||||
lda #<ptr1
|
||||
ldx #>ptr1
|
||||
jsr _SD_readSingleBlock
|
||||
|
||||
lda #<fatbuf
|
||||
ldx #>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
|
||||
ldx #>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 ; load the string "KERNEL O65"
|
||||
ldx #>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
|
||||
ldx #>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
|
||||
ldx #>filebuf
|
||||
jsr pushax
|
||||
lda #<ptr1
|
||||
ldx #>ptr1
|
||||
jsr _SD_readSingleBlock
|
||||
|
||||
lda #<filebuf
|
||||
ldx #>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"
|
||||
195
sw/bios/bootloader.s
Normal file
195
sw/bios/bootloader.s
Normal file
@@ -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
|
||||
ldx #>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
|
||||
ldx #>buf
|
||||
jsr pushax
|
||||
lda #<ptr1
|
||||
ldx #>ptr1
|
||||
jsr _SD_readSingleBlock
|
||||
|
||||
lda #<buf
|
||||
ldx #>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
|
||||
ldx #>buf
|
||||
jsr pushax
|
||||
lda #<ptr1
|
||||
ldx #>ptr1
|
||||
jsr _SD_readSingleBlock
|
||||
|
||||
stz sreg
|
||||
stz sreg+1
|
||||
pla
|
||||
plx
|
||||
inc
|
||||
jsr pusheax
|
||||
lda #<buf
|
||||
ldx #>buf
|
||||
inx
|
||||
inx
|
||||
jsr pushax
|
||||
lda #<ptr1
|
||||
ldx #>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
|
||||
|
||||
@@ -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
|
||||
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.
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
26
sw/bios/devices/sd_print.c
Normal file
26
sw/bios/devices/sd_print.c
Normal file
@@ -0,0 +1,26 @@
|
||||
#include <conio.h>
|
||||
|
||||
#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");
|
||||
}
|
||||
@@ -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 {
|
||||
51
sw/bios/main.c
Normal file
51
sw/bios/main.c
Normal file
@@ -0,0 +1,51 @@
|
||||
#include <stdint.h>
|
||||
#include <conio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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) ;
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -1,188 +0,0 @@
|
||||
#include <conio.h>
|
||||
|
||||
#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");
|
||||
}
|
||||
*/
|
||||
@@ -1,208 +0,0 @@
|
||||
#include <conio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
#ifndef _FAT_H
|
||||
#define _FAT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
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
|
||||
@@ -1,28 +0,0 @@
|
||||
#include <conio.h>
|
||||
|
||||
#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");
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
#ifndef _O65_H
|
||||
#define _O65_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#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
|
||||
@@ -1,81 +0,0 @@
|
||||
#include <stdint.h>
|
||||
#include <conio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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) ;
|
||||
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
2
sw/cc65
2
sw/cc65
Submodule sw/cc65 updated: 9dc33cff22...09e6c21f82
@@ -1 +0,0 @@
|
||||
hello, world!
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#ifndef _BOARD_IO_H
|
||||
#define _BOARD_IO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
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
|
||||
@@ -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
|
||||
@@ -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
|
||||
;_cgetc:
|
||||
;@2: lda _lastchar
|
||||
; beq @2
|
||||
; stz _lastchar
|
||||
; rts
|
||||
@@ -1,15 +0,0 @@
|
||||
#ifndef _INTERRUPT_H
|
||||
#define _INTERRUPT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#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
|
||||
@@ -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
|
||||
@@ -1,12 +0,0 @@
|
||||
#ifndef _MAPPER_H
|
||||
#define _MAPPER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void mapper_enable(uint8_t en);
|
||||
|
||||
uint8_t mapper_read(uint8_t addr);
|
||||
void mapper_write(uint8_t data, uint8_t addr);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
#include <stdint.h>
|
||||
#include <conio.h>
|
||||
|
||||
#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");
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
#ifndef _SD_CARD_H
|
||||
#define _SD_CARD_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
#include <stdint.h>
|
||||
#include <conio.h>
|
||||
#include <string.h>
|
||||
|
||||
#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);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
#ifndef _EXEC_H
|
||||
#define _EXEC_H
|
||||
|
||||
void exec(char* filename);
|
||||
|
||||
#endif
|
||||
@@ -1,246 +0,0 @@
|
||||
#include <conio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
#ifndef _FAT_H
|
||||
#define _FAT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
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
|
||||
@@ -1,28 +0,0 @@
|
||||
#include <conio.h>
|
||||
|
||||
#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");
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
#ifndef _O65_H
|
||||
#define _O65_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#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
|
||||
@@ -1,24 +0,0 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <conio.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
||||
9
sw/kernel/kernel.c
Normal file
9
sw/kernel/kernel.c
Normal file
@@ -0,0 +1,9 @@
|
||||
#include <conio.h>
|
||||
|
||||
int main() {
|
||||
cprintf("Hello, world!\r\n");
|
||||
|
||||
while(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
#include <stdint.h>
|
||||
#include <conio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
echo
|
||||
|
||||
@@ -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)"
|
||||
|
||||
|
||||
101
sw/script/o65dump.py
Executable file
101
sw/script/o65dump.py
Executable file
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user