From ca77db1734bc65e2eca0e57bc9c1f4cb67cb4732 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Sat, 9 Dec 2023 16:58:36 +0800 Subject: [PATCH] maple: add maple_host_bits --- main.cpp | 1 - maple/maple.cpp | 50 +++++++++-------------------- maple/maple_host_bits.h | 48 +++++++++++++++++++++++++++ regs/{maple.csv => maple_bits.csv} | 0 regs/{maple.ods => maple_bits.ods} | Bin regs/maple_host_bits.csv | 30 +++++++++++++++++ regs/maple_host_bits.ods | Bin 0 -> 14126 bytes 7 files changed, 94 insertions(+), 35 deletions(-) create mode 100644 maple/maple_host_bits.h rename regs/{maple.csv => maple_bits.csv} (100%) rename regs/{maple.ods => maple_bits.ods} (100%) create mode 100644 regs/maple_host_bits.csv create mode 100644 regs/maple_host_bits.ods diff --git a/main.cpp b/main.cpp index d3dd88e..7071c90 100644 --- a/main.cpp +++ b/main.cpp @@ -84,7 +84,6 @@ void maple_test() uint32_t * command_buf = align_32byte(_command_buf); uint32_t * receive_address = align_32byte(_receive_address); - serial_int(mdstar::table_address(reinterpret_cast(command_buf))); maple_init_host_command(command_buf, receive_address); maple_dma_start(command_buf); diff --git a/maple/maple.cpp b/maple/maple.cpp index 77fb592..022d732 100644 --- a/maple/maple.cpp +++ b/maple/maple.cpp @@ -7,55 +7,37 @@ #include "../systembus_bits.h" #include "maple_bits.h" +#include "maple_host_bits.h" #include "maple_bus_commands.h" #include "maple.h" -#define AP__PO__A (0b00 << 6) -#define AP__PO__B (0b01 << 6) -#define AP__PO__C (0b10 << 6) -#define AP__PO__D (0b11 << 6) - -#define AP__DE__DEVICE (1 << 5) -#define AP__DE__EXPANSION_DEVICE (0 << 5) -#define AP__DE__PORT (0 << 5) - -#define AP__LM(reg) ((reg) & 0b11111) - -// 2.6.8 "Peripheral Data Transfers" -// 5 "User Interface"; page 269 - -#define HOST_INSTRUCTION__END_FLAG (1 << 31) -#define HOST_INSTRUCTION__PORT_SELECT__A (0b00 << 16) -#define HOST_INSTRUCTION__PORT_SELECT__B (0b01 << 16) -#define HOST_INSTRUCTION__PORT_SELECT__C (0b10 << 16) -#define HOST_INSTRUCTION__PORT_SELECT__D (0b11 << 16) -#define HOST_INSTRUCTION__TRANSFER_LENGTH(n) (((n) & 0xff) << 0) - template struct maple_host_command { uint32_t host_instruction; uint32_t receive_data_storage_address; - uint8_t command_code; - uint8_t destination_ap; - uint8_t source_ap; - uint8_t data_size; - T data_fields; + struct bus_data { + uint8_t command_code; + uint8_t destination_ap; + uint8_t source_ap; + uint8_t data_size; + T data_fields; + } bus_data; }; void maple_init_host_command(uint32_t * buf, uint32_t * receive_address) { auto host_command = reinterpret_cast *>(buf); - host_command->host_instruction = HOST_INSTRUCTION__END_FLAG - | HOST_INSTRUCTION__PORT_SELECT__A - | HOST_INSTRUCTION__TRANSFER_LENGTH(0); // 4 bytes + host_command->host_instruction = host_instruction::end_flag + | host_instruction::port_select::a + | host_instruction::transfer_length(0); // 4 bytes host_command->receive_data_storage_address = reinterpret_cast(receive_address); - host_command->command_code = device_request::command_code; - host_command->destination_ap = AP__DE__DEVICE | AP__PO__A; - host_command->source_ap = AP__PO__A; - host_command->data_size = 0; + host_command->bus_data.command_code = device_request::command_code; + host_command->bus_data.destination_ap = ap::de::device | ap::port_select::a; + host_command->bus_data.source_ap = ap::port_select::a; + host_command->bus_data.data_size = 0; } void maple_dma_start(uint32_t * command_buf) @@ -76,7 +58,7 @@ void maple_dma_start(uint32_t * command_buf) // 20nsec * 0xc350 = 1ms constexpr uint32_t one_msec = 0xc350; maple_if.MSYS = msys::time_out_counter(one_msec) - | msys::sending_rate::_2M; + | msys::sending_rate::_2M; maple_if.MDTSEL = mdtsel::trigger_select::software_initiation; diff --git a/maple/maple_host_bits.h b/maple/maple_host_bits.h new file mode 100644 index 0000000..1949632 --- /dev/null +++ b/maple/maple_host_bits.h @@ -0,0 +1,48 @@ +#include + +#include "../float_uint32.h" + +namespace host_instruction { + constexpr uint32_t end_flag = 1 << 31; + + namespace port_select { + constexpr uint32_t a = 0 << 16; + constexpr uint32_t b = 1 << 16; + constexpr uint32_t c = 2 << 16; + constexpr uint32_t d = 3 << 16; + } + + namespace pattern { + constexpr uint32_t normal = 0b000 << 8; + constexpr uint32_t light_gun_mode = 0b010 << 8; + constexpr uint32_t reset = 0b011 << 8; + constexpr uint32_t return_from_light_gun_mode = 0b100 << 8; + constexpr uint32_t nop = 0b111 << 8; + } + + constexpr uint32_t transfer_length(uint32_t num) { return (num & 0xff) << 0; } +} + +namespace ap { + namespace port_select { + constexpr uint32_t a = 0b00 << 6; + constexpr uint32_t b = 0b01 << 6; + constexpr uint32_t c = 0b10 << 6; + constexpr uint32_t d = 0b11 << 6; + } + + namespace de { + constexpr uint32_t device = 1 << 5; + constexpr uint32_t expansion_device = 0 << 5; + constexpr uint32_t port = 0 << 5; + } + + namespace lm_bus { + constexpr uint32_t _4 = 0b10000 << 0; + constexpr uint32_t _3 = 0b01000 << 0; + constexpr uint32_t _2 = 0b00100 << 0; + constexpr uint32_t _1 = 0b00010 << 0; + constexpr uint32_t _0 = 0b00001 << 0; + } +} + diff --git a/regs/maple.csv b/regs/maple_bits.csv similarity index 100% rename from regs/maple.csv rename to regs/maple_bits.csv diff --git a/regs/maple.ods b/regs/maple_bits.ods similarity index 100% rename from regs/maple.ods rename to regs/maple_bits.ods diff --git a/regs/maple_host_bits.csv b/regs/maple_host_bits.csv new file mode 100644 index 0000000..febbbe6 --- /dev/null +++ b/regs/maple_host_bits.csv @@ -0,0 +1,30 @@ +"register_name","enum_name","bits","bit_name","value","mask","description" +"host_instruction",,31,"end_flag",1,, +,,,,,, +"host_instruction","port_select","17-16","a",0,, +"host_instruction","port_select","17-16","b",1,, +"host_instruction","port_select","17-16","c",2,, +"host_instruction","port_select","17-16","d",3,, +,,,,,, +"host_instruction","pattern","10-8","normal","0b000",, +"host_instruction","pattern","10-8","light_gun_mode","0b010",, +"host_instruction","pattern","10-8","reset","0b011",, +"host_instruction","pattern","10-8","return_from_light_gun_mode","0b100",, +"host_instruction","pattern","10-8","nop","0b111",, +,,,,,, +"host_instruction",,"7-0","transfer_length",,"0xff", +,,,,,, +"ap","port_select","7-6","a","0b00",, +"ap","port_select","7-6","b","0b01",, +"ap","port_select","7-6","c","0b10",, +"ap","port_select","7-6","d","0b11",, +,,,,,, +"ap","de",5,"device",1,, +"ap","de",5,"expansion_device",0,, +"ap","de",5,"port",0,, +,,,,,, +"ap","lm_bus","4-0","_4","0b10000",, +"ap","lm_bus","4-0","_3","0b01000",, +"ap","lm_bus","4-0","_2","0b00100",, +"ap","lm_bus","4-0","_1","0b00010",, +"ap","lm_bus","4-0","_0","0b00001",, diff --git a/regs/maple_host_bits.ods b/regs/maple_host_bits.ods new file mode 100644 index 0000000000000000000000000000000000000000..f06e2796faf4ffa3331face35501dd95000460eb GIT binary patch literal 14126 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 bo`0~?>Pjf^%o_jz5B{@)8=YF-`>X!}dvB>! literal 0 HcmV?d00001