From 855cbba4032f5af93fec436beb67e91ad487fc19 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Mon, 11 Dec 2023 18:07:05 +0800 Subject: [PATCH] maple: write data to a VMU display This draws a smiley-face bitmap to a VMU display on port 1. --- Makefile | 1 + common.mk | 2 +- main.cpp | 52 ++++++++++++++++++++++++++++++------------- maple/maple.cpp | 57 ++++++++++++++++++++++++++++++------------------ maple/maple.h | 14 ++++++++++++ wink.data | Bin 0 -> 1536 bytes wink.png | Bin 0 -> 8863 bytes 7 files changed, 89 insertions(+), 37 deletions(-) create mode 100644 wink.data create mode 100644 wink.png diff --git a/Makefile b/Makefile index 58af89d..63ed3dd 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,7 @@ MAIN_OBJ = \ maple/maple.o \ scene.o \ macaw.data.o \ + wink.data.o \ $(LIBGCC) serial.elf: start.o serial_main.o load.o cache.o diff --git a/common.mk b/common.mk index 72be8e3..6db30bc 100644 --- a/common.mk +++ b/common.mk @@ -1,5 +1,5 @@ LIB ?= . -OPT ?= -Os +OPT ?= -Og DEBUG ?= -g -gdwarf-4 GENERATED ?= diff --git a/main.cpp b/main.cpp index a2af41a..6ae5739 100644 --- a/main.cpp +++ b/main.cpp @@ -95,33 +95,54 @@ void serial_int8(const uint8_t n) serial_string("\n"); } -uint32_t _receive_address[(32 + 32) / 4] = {0}; -uint32_t _command_buf[(32 + 32) / 4] = {0}; +uint32_t _receive_address[(256 + 32) / 4] = {0}; +uint32_t _command_buf[(256 + 32) / 4] = {0}; + +extern uint32_t _binary_wink_data_start __asm("_binary_wink_data_start"); + +void make_wink(uint32_t * buf) +{ + const uint8_t * src = reinterpret_cast(&_binary_wink_data_start); + uint8_t * dst = reinterpret_cast(buf); + + uint32_t ix = 0; + dst[ix] = 0; + for (int i = 0; i < 48 * 32; i++) { + dst[ix] |= ((src[i] & 1) << (7 - (i % 8))); + + if (i % 8 == 7) { + ix++; + dst[ix] = 0; + } + } +} bool maple_test() { + v_sync_out(); + uint32_t * command_buf = align_32byte(_command_buf); uint32_t * receive_address = align_32byte(_receive_address); if ((((uint32_t)command_buf) & 31) != 0) serial_string("misaligned\n"); if ((((uint32_t)receive_address) & 31) != 0) serial_string("misaligned\n"); - for (int i = 0; i < (32 / 4); i++) { - command_buf[i] = 0; - } - - for (int i = 0; i < (32 / 4); i++) { - receive_address[i] = 0; - } - - v_sync_out(); - //maple_init_device_request(command_buf, receive_address); - maple_init_get_condition(command_buf, receive_address); + //maple_init_get_condition(command_buf, receive_address); + uint32_t wink_buf[192]; + make_wink(wink_buf); + maple_init_block_write(command_buf, receive_address, wink_buf); + + serial_int32(command_buf[0]); + serial_char('\n'); maple_dma_start(command_buf); v_sync_in(); + for (int i = 0; i < 32; i++) { + serial_int32(receive_address[i]); + } + /* for (int i = 0; i < (4 + 4 + 8); i++) { serial_int8(reinterpret_cast(receive_address)[i]); @@ -149,7 +170,8 @@ void main() vga(); - v_sync_in(); + maple_test(); + //((void(*)(void))0xac010000)(); /* volatile uint16_t * framebuffer = reinterpret_cast(&texture_memory[0]); @@ -213,7 +235,7 @@ void main() ta_wait_opaque_list(); core_start_render(frame); - a_pressed = maple_test(); + //a_pressed = maple_test(); frame = !frame; } diff --git a/maple/maple.cpp b/maple/maple.cpp index 7bf3259..a0762aa 100644 --- a/maple/maple.cpp +++ b/maple/maple.cpp @@ -11,19 +11,6 @@ #include "maple_bus_commands.h" #include "maple.h" -template -struct maple_host_command { - uint32_t host_instruction; - uint32_t receive_data_storage_address; - 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, uint8_t command_code, uint8_t data_size) { // this function does not care about the template instantiation of @@ -31,13 +18,13 @@ void maple_init_host_command(uint32_t * buf, uint32_t * receive_address, uint8_t auto host_command = reinterpret_cast *>(buf); host_command->host_instruction = host_instruction::end_flag - | host_instruction::port_select::a - | host_instruction::transfer_length((data_size / 4)); + | host_instruction::port_select::a + | host_instruction::transfer_length((data_size / 4)); host_command->receive_data_storage_address = reinterpret_cast(receive_address) & 0x1fff'ffff; host_command->bus_data.command_code = command_code; - host_command->bus_data.destination_ap = ap::de::device | ap::port_select::a; + host_command->bus_data.destination_ap = ap::de::expansion_device | ap::port_select::a | ap::lm_bus::_0; host_command->bus_data.source_ap = ap::port_select::a; host_command->bus_data.data_size = data_size / 4; } @@ -61,11 +48,39 @@ void maple_init_get_condition(uint32_t * buf, uint32_t * receive_address) function_type[3] = 0x01; } +void maple_init_block_write(uint32_t * buf, uint32_t * receive_address, uint32_t * data) +{ + maple_init_host_command(buf, receive_address, block_write::command_code, (sizeof (struct block_write::data_fields))); + + auto host_command = reinterpret_cast> *>(buf); + + auto& fields = host_command->bus_data.data_fields; + // BW LCD function type + fields.function_type[0] = 0x00; + fields.function_type[1] = 0x00; + fields.function_type[2] = 0x00; + fields.function_type[3] = 0x04; + + // lcd number 0 (1 total lcd) + fields.pt[0] = 0; + + // phase 0 (from 0 to 3) + fields.phase[0] = 0; + + // plane 0 (2 total levels of gradation) + fields.block_no[0] = 0x00; + fields.block_no[1] = 0x00; + + for (uint32_t i = 0; i < (192 / 4); i++) { + fields.written_data[i] = data[i]; + } +} + 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 */ + | 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; @@ -78,13 +93,13 @@ 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; /* top address: the first/lowest address bottom address: the last/highest address */ maple_if.MDAPRO = mdapro::security_code - | mdapro::top_address(0x00) - | mdapro::bottom_address(0x7f); + | mdapro::top_address(0x00) + | mdapro::bottom_address(0x7f); maple_if.MDTSEL = mdtsel::trigger_select::software_initiation; diff --git a/maple/maple.h b/maple/maple.h index f756759..621542e 100644 --- a/maple/maple.h +++ b/maple/maple.h @@ -2,7 +2,21 @@ #include +template +struct maple_host_command { + uint32_t host_instruction; + uint32_t receive_data_storage_address; + 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); void maple_init_device_request(uint32_t * buf, uint32_t * receive_address); void maple_init_get_condition(uint32_t * buf, uint32_t * receive_address); +void maple_init_block_write(uint32_t * buf, uint32_t * receive_address, uint32_t * data); void maple_dma_start(uint32_t * command_buf); diff --git a/wink.data b/wink.data new file mode 100644 index 0000000000000000000000000000000000000000..814ff337d604d2f5fde0c1189142ce1701b82eb0 GIT binary patch literal 1536 zcmeH_OAdfA2t@1sFD=ZJ7L|5 zw3mhnMj%}qc}ek6y;)RS6x&A&bQwTK>s?UWKG2HSqWp77KIBC_HA(mSm~D#dB)wwy O#-h~#W96TDZv!WJfdFs- literal 0 HcmV?d00001 diff --git a/wink.png b/wink.png new file mode 100644 index 0000000000000000000000000000000000000000..f3ed8b1d5d57e7428649bdc5d5b0e7b1fd71f1fd GIT binary patch literal 8863 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 literal 0 HcmV?d00001