diff --git a/maple-notes.txt b/maple-notes.txt index debb191..4f791e4 100644 --- a/maple-notes.txt +++ b/maple-notes.txt @@ -6,18 +6,21 @@ MAPLE82E.pdf Chapter 6 "COMMAND REFERENCE" jargon: -AP - Absolute Position ; MAPLE82E.pdf page 13 +AP - Absolute Position ; MAPLE82E.pdf page 13 / page 21 (Address) (Data) 0x0C700000 → 0x00000000 Port 0, 4-byte data transmission (instruction to Maple-Host) 0x0C700004 → 0x0C800000 Port 0, reception data storage address (instruction to Maple-Host) 0x0C700008 → 0x01200000 [Device Request], transfer destination AP: 0x20, transfer source AP: 0x00 + 0x0C70000C → 0x00010000 Port 1, 4-byte data transmission 0x0C700010 → 0x0C800100 Port 1, reception data storage address 0x0C700014 → 0x01604000 [Device Request], transfer destination AP: 0x60, transfer source AP: 0x40 + 0x0C700018 → 0x00020000 Port 2, 4-byte data transmission 0x0C70001C → 0x0C800200 Port 2, reception data storage address 0x0C700020 → 0x01A08000 [Device Request], transfer destination AP: 0xA0, transfer source AP: 0x80 + 0x0C700024 → 0x80030000 Port 3, 4-byte data transmission 0x0C700028 → 0x0C800300 Port 3, reception data storage address 0x0C70002C → 0x01E0C000 [Device Request], transfer destination AP: 0xE0, transfer source AP: 0xC0 @@ -50,3 +53,38 @@ AP - Absolute Position ; MAPLE82E.pdf page 13 0x0C700034 → 0x0C800300 Port 3, reception data storage address 0x0C700038 → 0x09E0C001 [Get Condition], transfer destination AP: 0xC0, transfer source AP: 0xE0 0x0C70003C → 0x00000001 Function Type + +--- + +SB_MDSTAR 0x005F6C04: Starting address setting for the command table in system memory + Settable area: 0x0C000000 - 0x0FFFFFE0 + +SB_MDTSEL 0x005F6C10: Maple-DMA trigger setting + 0x00000000 : Software trigger + 0x00000001 : Hardware trigger + +SB_MDEN 0x005F6C14: Enables Maple-DMA + (Read) + 0x00000000 : Disable + 0x00000001 : Enable + (Write) + 0x00000000 : Disable + 0x00000001 : Enable + +SB_MDST 0x005F6C18: Maple-DMA software start + (Read) + 0x00000000 : Maple-DMA end + 0x00000001 : Maple-DMA transfer in progress + (Write) + 0x00000000 : Invalid + 0x00000001 : Maple-DMA start + +SB_MSYS 0x005F6C80: Maple system control setting + For details, refer to section 8.4.1.1, "System Registers." + +SB_MDAPRO 0x005F6C8C: Maple-DMA area protection setting + Settable area: 0x0C000000 to 0x0FFFFFE0 + +SB_ISTNRM 0x005F6900: Normal interrupt status + bit12: Maple-DMA end + For details on interrupt registers, refer to section 8.4.1.1, "System Registers." diff --git a/maple.cpp b/maple.cpp new file mode 100644 index 0000000..24c7600 --- /dev/null +++ b/maple.cpp @@ -0,0 +1,86 @@ +#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; + uint32_t protocol_data[N]; +}; + +void maple_host_command(uint32_t * buf, uint32_t * receive_address) +{ + auto command = reinterpet_cast *>(buf); + + command->host_instruction = HOST_INSTRUCTION__END_FLAG + | HOST_INSTRUCTION__PORT_SELECT__A + | HOST_INSTRUCTION__TRANSFER_LENGTH(0); // 4 bytes + + command->receive_data_storage_address = reinterpret_cast(receive_address); + + uint32_t command_code = 0x01; // 'Device Request' + uint32_t destination_ap = AP__DE__DEVICE | AP__PO__A; + uint32_t source_ap = AP__PO__A; + uint32_t data_size = 0; + command->protocol_data[0] = (command_code << 24) + | (destination_ap << 16) + | (source_ap << 8) + | (data_size << 0); +} + +void maple_dma_start(uint32_t * command_buf) +{ + sh7091.DMAC.DMAOR = DMAOR__DDT /* on-demand data transfer mode */ + | DMAOR__PR__CH2_CH0_CH1_CH3 /* priority mode; CH2 > CH0 > CH1 > CH3 */ + | DMAOR__DME; /* DMAC master enable */ + + // clear maple-DMA end status + system.ISTNRM = ISTNRM__END_OF_DMA_MAPLE_DMA; + + // disable maple-DMA + system.MDEN = mden::dma_enable::abort; + + volatile uint32_t _dummy = system.MDST; + (void)_dummy; + + // 20nsec * 0xc350 = 1ms + constexpr uint32_t one_msec = 0xc350; + system.MSYS = msys::time_out_counter(one_msec) + | msys::sending_rate::_2M; + + system.MDTSEL = mdtsel::trigger_select::software_initiation; + + /* top address: the first/lowest address + bottom address: the last/highest address */ + system.MDAPRO = mdapro::security_code + | mdapro::top_address(0x00) + | mdapro::bottom_address(0x7f); + + system.MDSTAR = mdstar::table_address(command_buf); + + system.MDEN = mden::dma_enable::enable; + system.MDST = mdst::start_status::start; + + // wait for completion + while ((system.ISTNRM & ISTNRM__END_OF_DMA_MAPLE_DMA) == 0); + + system.ISTNRM = ISTNRM__END_OF_DMA_MAPLE_DMA; +} diff --git a/maple.h b/maple.h new file mode 100644 index 0000000..2a528cf --- /dev/null +++ b/maple.h @@ -0,0 +1,78 @@ +#include + +#include "float_uint32.h" + +namespace mdstar { + constexpr uint32_t table_address(uint32_t num) { return (num & 0xfffffe0) << 0; } +} + +namespace mdtsel { + namespace trigger_select { + constexpr uint32_t software_initiation = 0 << 0; + constexpr uint32_t v_blank_initiation = 1 << 0; + } +} + +namespace mden { + namespace dma_enable { + constexpr uint32_t abort = 0 << 0; + constexpr uint32_t enable = 1 << 0; + constexpr uint32_t status(uint32_t reg) { return (reg >> 0) & 0x1; } + } +} + +namespace mdst { + namespace start_status { + constexpr uint32_t status(uint32_t reg) { return (reg >> 0) & 0x1; } + constexpr uint32_t start = 1 << 0; + } +} + +namespace msys { + constexpr uint32_t time_out_counter(uint32_t num) { return (num & 0xffff) << 16; } + constexpr uint32_t single_hard_trigger = 1 << 12; + + namespace sending_rate { + constexpr uint32_t _2M = 0 << 8; + constexpr uint32_t _1M = 1 << 8; + } + + constexpr uint32_t delay_time(uint32_t num) { return (num & 0xf) << 0; } +} + +namespace mst { + constexpr uint32_t move_status(uint32_t reg) { return (reg >> 31) & 0x1; } + constexpr uint32_t internal_frame_monitor(uint32_t reg) { return (reg >> 24) & 0x7; } + constexpr uint32_t internal_state_monitor(uint32_t reg) { return (reg >> 16) & 0x3f; } + constexpr uint32_t line_monitor(uint32_t reg) { return (reg >> 0) & 0xff; } +} + +namespace mshtcl { + constexpr uint32_t hard_dma_clear = 1 << 0; +} + +namespace mdapro { + constexpr uint32_t security_code = 0x6155 << 16; + constexpr uint32_t top_address(uint32_t num) { return (num & 0x7f) << 8; } + constexpr uint32_t bottom_address(uint32_t num) { return (num & 0x7f) << 0; } +} + +namespace mmsel { + namespace msb_selection { + constexpr uint32_t bit7 = 0 << 0; + constexpr uint32_t bit31 = 1 << 0; + } +} + +namespace mtxdad { + constexpr uint32_t txd_address_counter(uint32_t reg) { return (reg >> 0) & 0x1fffffff; } +} + +namespace mrxdad { + constexpr uint32_t rxd_address_counter(uint32_t reg) { return (reg >> 0) & 0x1fffffff; } +} + +namespace mrxdbd { + constexpr uint32_t rxd_base_address(uint32_t reg) { return (reg >> 0) & 0x1fffffff; } +} + diff --git a/regs/maple.csv b/regs/maple.csv new file mode 100644 index 0000000..1f74217 --- /dev/null +++ b/regs/maple.csv @@ -0,0 +1,38 @@ +"register_name","enum_name","bits","bit_name","value","mask","description" +"MDSTAR",,"27-0","table_address",,"0xfffffe0", +,,,,,, +"MDTSEL","trigger_select",0,"software_initiation",0,, +"MDTSEL","trigger_select",0,"v_blank_initiation",1,, +,,,,,, +"MDEN","dma_enable",0,"abort",0,, +"MDEN","dma_enable",0,"enable",1,, +"MDEN","dma_enable",0,"status",,, +,,,,,, +"MDST","start_status",0,"status",,, +"MDST","start_status",0,"start",1,, +,,,,,, +"MSYS",,"31-16","time_out_counter",,"0xffff", +"MSYS",,12,"single_hard_trigger",1,, +"MSYS","sending_rate","9-8","_2M",0,, +"MSYS","sending_rate","9-8","_1M",1,, +"MSYS",,"3-0","delay_time",,"0xf", +,,,,,, +"MST",,31,"move_status",,, +"MST",,"26-24","internal_frame_monitor",,, +"MST",,"21-16","internal_state_monitor",,, +"MST",,"7-0","line_monitor",,, +,,,,,, +"MSHTCL",,0,"hard_dma_clear",1,, +,,,,,, +"MDAPRO",,"31-16","security_code","0x6155",, +"MDAPRO",,"14-8","top_address",,"0x7f", +"MDAPRO",,"6-0","bottom_address",,"0x7f", +,,,,,, +"MMSEL","msb_selection",0,"bit7",0,, +"MMSEL","msb_selection",0,"bit31",1,, +,,,,,, +"MTXDAD",,"28-0","txd_address_counter",,, +,,,,,, +"MRXDAD",,"28-0","rxd_address_counter",,, +,,,,,, +"MRXDBD",,"28-0","rxd_base_address",,, diff --git a/regs/maple.ods b/regs/maple.ods new file mode 100644 index 0000000..abbd202 Binary files /dev/null and b/regs/maple.ods differ