diff --git a/Makefile b/Makefile index 63ed3dd..c736c7a 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,10 @@ all: main.elf include common.mk +include example/example.mk MAIN_OBJ = \ - start.o \ main.o \ - load.o \ - cache.o \ vga.o \ rgb.o \ holly/background.o \ @@ -16,14 +14,13 @@ MAIN_OBJ = \ maple/maple.o \ scene.o \ macaw.data.o \ - wink.data.o \ - $(LIBGCC) + wink.data.o -serial.elf: start.o serial_main.o load.o cache.o - $(LD) $(LDFLAGS) -T $(LIB)/alt.lds $^ -o $@ +serial.elf: LDSCRIPT = $(LIB)/alt.lds +serial.elf: $(START_OBJ) serial_main.o load.o -main.elf: $(MAIN_OBJ) - $(LD) $(LDFLAGS) -T $(LIB)/main.lds $^ -o $@ +main.elf: LDSCRIPT = $(LIB)/main.lds +main.elf: $(START_OBJ) $(MAIN_OBJ) -test.elf: $(MAIN_OBJ) - $(LD) $(LDFLAGS) -T $(LIB)/alt.lds $^ -o $@ +test.elf: LDSCRIPT = $(LIB)/alt.lds +test.elf: $(START_OBJ) $(MAIN_OBJ) diff --git a/aica.h b/aica.hpp similarity index 100% rename from aica.h rename to aica.hpp diff --git a/align.hpp b/align.hpp new file mode 100644 index 0000000..fae4dbe --- /dev/null +++ b/align.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include + +template +inline T * align_32byte(T * mem) +{ + return reinterpret_cast((((reinterpret_cast(mem) + 31) & ~31))); +} diff --git a/cache.cpp b/cache.cpp index 9f4b401..8dea9e6 100644 --- a/cache.cpp +++ b/cache.cpp @@ -1,13 +1,15 @@ -#include "type.h" -#include "sh7091.h" -#include "sh7091_bits.h" +#include "type.hpp" +#include "sh7091.hpp" +#include "sh7091_bits.hpp" -#include "cache.h" +#include "cache.hpp" extern volatile reg32 sh7091_ic_a[256][(1 << 5) / 4] __asm("sh7091_ic_a"); extern volatile reg32 sh7091_oc_a[512][(1 << 5) / 4] __asm("sh7091_oc_a"); -void cache_init() +namespace cache { + +void init() { for (int i = 0; i < 256; i++) { sh7091_ic_a[i][0] = 0; @@ -28,3 +30,5 @@ void cache_init() asm volatile ("nop;nop;nop;nop;nop;nop;nop;nop;"); } + +} diff --git a/cache.h b/cache.h deleted file mode 100644 index 91397b9..0000000 --- a/cache.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void cache_init() __attribute__ ((section (".p2ram.cache_init"))); diff --git a/cache.hpp b/cache.hpp new file mode 100644 index 0000000..192c228 --- /dev/null +++ b/cache.hpp @@ -0,0 +1,7 @@ +#pragma once + +namespace cache { + +void init() __attribute__ ((section (".p2ram.cache_init"))); + +} diff --git a/common.mk b/common.mk index 6db30bc..58f10fd 100644 --- a/common.mk +++ b/common.mk @@ -1,5 +1,8 @@ +MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) +DIR := $(dir $(MAKEFILE_PATH)) + LIB ?= . -OPT ?= -Og +OPT ?= -Os DEBUG ?= -g -gdwarf-4 GENERATED ?= @@ -11,6 +14,7 @@ CFLAGS += -falign-functions=4 -ffunction-sections -fdata-sections -fshort-enums CFLAGS += -Wall -Werror -Wfatal-errors CFLAGS += -Wno-error=narrowing -Wno-error=unused-variable CFLAGS += -mfsca -funsafe-math-optimizations +CFLAGS += -I$(dir $(MAKEFILE_PATH)) DEPFLAGS = -MMD -E # --print-gc-sections LDFLAGS = --gc-sections --no-warn-rwx-segment --print-memory-usage --entry=_start --orphan-handling=error @@ -48,6 +52,11 @@ IP_OBJ = \ sg/sg_ini.o \ sg/aip.o +START_OBJ = \ + start.o \ + runtime.o \ + cache.o + %.bin.o: %.bin $(BUILD_BINARY_O) @@ -71,6 +80,9 @@ IP_OBJ = \ %.o: %.cpp %.cpp.d $(CXX) $(CARCH) $(CFLAGS) $(CXXFLAGS) $(OPT) $(DEBUG) -c $< -o $@ +%.elf: + $(LD) $(LDFLAGS) -T $(LDSCRIPT) $^ -o $@ + %.bin: %.elf $(OBJCOPY) -O binary $< $@ diff --git a/example/cube.cpp b/example/cube.cpp new file mode 100644 index 0000000..879df23 --- /dev/null +++ b/example/cube.cpp @@ -0,0 +1,12 @@ +#include + +#include "vga.hpp" +#include "memorymap.hpp" +#include "rgb.hpp" + +void main() +{ + vga(); + + while (1); +} diff --git a/example/example.mk b/example/example.mk new file mode 100644 index 0000000..2434323 --- /dev/null +++ b/example/example.mk @@ -0,0 +1,17 @@ +CUBE_OBJ = \ + example/cube.o \ + vga.o + +example/cube.elf: LDSCRIPT = $(LIB)/alt.lds +example/cube.elf: $(START_OBJ) $(CUBE_OBJ) + +MAPLE_WINK_OBJ = \ + example/maple_wink.o \ + vga.o \ + rgb.o \ + serial.o \ + maple/maple.o \ + wink.data.o + +example/maple_wink.elf: LDSCRIPT = $(LIB)/alt.lds +example/maple_wink.elf: $(START_OBJ) $(MAPLE_WINK_OBJ) diff --git a/example/maple_wink.cpp b/example/maple_wink.cpp new file mode 100644 index 0000000..6e105e0 --- /dev/null +++ b/example/maple_wink.cpp @@ -0,0 +1,52 @@ +#include + +#include "maple/maple.hpp" +#include "vga.hpp" +#include "align.hpp" +#include "serial.hpp" + +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; + } + } +} + +void main() +{ + constexpr int width = 48; + constexpr int height = 32; + constexpr int pixels_per_byte = 8; + + uint32_t wink_buf[width * height / pixels_per_byte]; + make_wink(wink_buf); + + uint32_t _command_buf[128 / 4]; + uint32_t _receive_buf[128 / 4]; + uint32_t * command_buf = align_32byte(_command_buf); + uint32_t * receive_buf = align_32byte(_receive_buf); + + maple::init_block_write(command_buf, receive_buf, wink_buf); + maple::dma_start(command_buf); + + for (int i = 0; i < 32; i++) { + serial::integer(receive_buf[i]); + } + + vga(); + v_sync_in(); + vga_fill_framebuffer(); + while(1); +} diff --git a/serial_main.cpp b/example/serial_transfer.cpp similarity index 83% rename from serial_main.cpp rename to example/serial_transfer.cpp index e3d0d4a..f5e89f9 100644 --- a/serial_main.cpp +++ b/example/serial_transfer.cpp @@ -1,8 +1,10 @@ -#include "sh7091.h" -#include "sh7091_bits.h" +#include -#include "cache.h" -#include "load.h" +#include "sh7091.hpp" +#include "sh7091_bits.hpp" + +#include "cache.hpp" +#include "load.hpp" extern uint32_t __bss_link_start __asm("__bss_link_start"); extern uint32_t __bss_link_end __asm("__bss_link_end"); diff --git a/float_uint32.h b/float_uint32.hpp similarity index 100% rename from float_uint32.h rename to float_uint32.hpp diff --git a/holly.h b/holly.hpp similarity index 99% rename from holly.h rename to holly.hpp index 7287787..6458a44 100644 --- a/holly.h +++ b/holly.hpp @@ -1,7 +1,7 @@ -#include -#include +#include +#include -#include "type.h" +#include "type.hpp" struct holly_reg { reg32 ID; /* Device ID */ diff --git a/holly/background.cpp b/holly/background.cpp index a4da067..5fd72a9 100644 --- a/holly/background.cpp +++ b/holly/background.cpp @@ -1,6 +1,6 @@ #include -#include "isp_tsp.h" +#include "isp_tsp.hpp" struct vertex_parameter { float x; diff --git a/holly/background.h b/holly/background.hpp similarity index 100% rename from holly/background.h rename to holly/background.hpp diff --git a/holly/core.cpp b/holly/core.cpp index 8aa531e..246cc41 100644 --- a/holly/core.cpp +++ b/holly/core.cpp @@ -1,13 +1,13 @@ -#include "../float_uint32.h" -#include "core_bits.h" -#include "../holly.h" -#include "../memorymap.h" +#include "../float_uint32.hpp" +#include "core_bits.hpp" +#include "../holly.hpp" +#include "../memorymap.hpp" -#include "texture_memory_alloc.h" +#include "texture_memory_alloc.hpp" -#include "core.h" -#include "background.h" -#include "region_array.h" +#include "core.hpp" +#include "background.hpp" +#include "region_array.hpp" void core_init() { diff --git a/holly/core.h b/holly/core.hpp similarity index 100% rename from holly/core.h rename to holly/core.hpp diff --git a/holly/core_bits.h b/holly/core_bits.hpp similarity index 99% rename from holly/core_bits.h rename to holly/core_bits.hpp index 772da55..3b25c11 100644 --- a/holly/core_bits.h +++ b/holly/core_bits.hpp @@ -1,6 +1,6 @@ #include -#include "../float_uint32.h" +#include "../float_uint32.hpp" namespace id { constexpr uint32_t device_id(uint32_t reg) { return (reg >> 16) & 0xffff; } diff --git a/holly/isp_tsp.h b/holly/isp_tsp.hpp similarity index 100% rename from holly/isp_tsp.h rename to holly/isp_tsp.hpp diff --git a/holly/region_array.cpp b/holly/region_array.cpp index 64e139a..f09057c 100644 --- a/holly/region_array.cpp +++ b/holly/region_array.cpp @@ -1,4 +1,6 @@ -#include "region_array.h" +#include + +#include "region_array.hpp" #define REGION_ARRAY__LAST_REGION (1 << 31) #define REGION_ARRAY__Z_CLEAR (1 << 30) diff --git a/holly/region_array.h b/holly/region_array.hpp similarity index 100% rename from holly/region_array.h rename to holly/region_array.hpp diff --git a/holly/ta_bits.h b/holly/ta_bits.hpp similarity index 99% rename from holly/ta_bits.h rename to holly/ta_bits.hpp index ce28ee6..1bf9ee6 100644 --- a/holly/ta_bits.h +++ b/holly/ta_bits.hpp @@ -1,6 +1,6 @@ #include -#include "../float_uint32.h" +#include "../float_uint32.hpp" namespace ta_ol_base { constexpr uint32_t base_address(uint32_t num) { return (num & 0xffffe0) << 0; } diff --git a/holly/ta_fifo_polygon_converter.cpp b/holly/ta_fifo_polygon_converter.cpp index fe43d3a..da05fbc 100644 --- a/holly/ta_fifo_polygon_converter.cpp +++ b/holly/ta_fifo_polygon_converter.cpp @@ -1,16 +1,16 @@ #include -#include "core_bits.h" -#include "ta_bits.h" -#include "../holly.h" -#include "../systembus.h" -#include "../systembus_bits.h" -#include "../sh7091.h" -#include "../sh7091_bits.h" +#include "core_bits.hpp" +#include "ta_bits.hpp" +#include "../holly.hpp" +#include "../systembus.hpp" +#include "../systembus_bits.hpp" +#include "../sh7091.hpp" +#include "../sh7091_bits.hpp" -#include "texture_memory_alloc.h" +#include "texture_memory_alloc.hpp" -#include "ta_fifo_polygon_converter.h" +#include "ta_fifo_polygon_converter.hpp" void ta_polygon_converter_init() { diff --git a/holly/ta_fifo_polygon_converter.h b/holly/ta_fifo_polygon_converter.hpp similarity index 100% rename from holly/ta_fifo_polygon_converter.h rename to holly/ta_fifo_polygon_converter.hpp diff --git a/holly/ta_parameter.h b/holly/ta_parameter.hpp similarity index 99% rename from holly/ta_parameter.h rename to holly/ta_parameter.hpp index 963c33e..fdf679b 100644 --- a/holly/ta_parameter.h +++ b/holly/ta_parameter.hpp @@ -1,8 +1,8 @@ #include #include -#include "../float_uint32.h" -#include "isp_tsp.h" +#include "../float_uint32.hpp" +#include "isp_tsp.hpp" namespace para_control { namespace para_type { diff --git a/holly/texture_memory_alloc.h b/holly/texture_memory_alloc.hpp similarity index 100% rename from holly/texture_memory_alloc.h rename to holly/texture_memory_alloc.hpp diff --git a/imask.h b/imask.hpp similarity index 100% rename from imask.h rename to imask.hpp diff --git a/load.cpp b/load.cpp index 49b1b7d..9e12807 100644 --- a/load.cpp +++ b/load.cpp @@ -1,8 +1,8 @@ -#include +#include -#include "sh7091.h" -#include "sh7091_bits.h" -#include "holly.h" +#include "sh7091.hpp" +#include "sh7091_bits.hpp" +#include "holly.hpp" enum load_command { CMD_NONE, diff --git a/load.h b/load.hpp similarity index 100% rename from load.h rename to load.hpp diff --git a/macaw.h b/macaw.hpp similarity index 100% rename from macaw.h rename to macaw.hpp diff --git a/main.cpp b/main.cpp index 6ae5739..07f2e96 100644 --- a/main.cpp +++ b/main.cpp @@ -1,67 +1,29 @@ -#include +#include -#include "memorymap.h" +#include "memorymap.hpp" -#include "sh7091.h" -#include "sh7091_bits.h" -#include "holly.h" -#include "holly/core.h" -#include "holly/core_bits.h" -#include "holly/ta_fifo_polygon_converter.h" -#include "systembus.h" -#include "maple/maple.h" -#include "maple/maple_bits.h" -#include "maple/maple_bus_commands.h" -#include "maple/maple_bus_ft0.h" +#include "sh7091.hpp" +#include "sh7091_bits.hpp" +#include "holly.hpp" +#include "holly/core.hpp" +#include "holly/core_bits.hpp" +#include "holly/ta_fifo_polygon_converter.hpp" +#include "systembus.hpp" +#include "maple/maple.hpp" +#include "maple/maple_bits.hpp" +#include "maple/maple_bus_commands.hpp" +#include "maple/maple_bus_ft0.hpp" -#include "holly/texture_memory_alloc.h" +#include "holly/texture_memory_alloc.hpp" -#include "cache.h" -#include "load.h" -#include "vga.h" -#include "rgb.h" -#include "string.h" -#include "scene.h" +#include "cache.hpp" +#include "load.hpp" +#include "vga.hpp" +#include "rgb.hpp" +#include "string.hpp" +#include "scene.hpp" -#include "macaw.h" - -extern uint32_t __bss_link_start __asm("__bss_link_start"); -extern uint32_t __bss_link_end __asm("__bss_link_end"); - -void serial() -{ - sh7091.SCIF.SCSCR2 = 0; - sh7091.SCIF.SCSMR2 = 0; - sh7091.SCIF.SCBRR2 = 1; // 520833.3 - - sh7091.SCIF.SCFCR2 = SCFCR2__TFRST | SCFCR2__RFRST; - // tx/rx trigger on 1 byte - sh7091.SCIF.SCFCR2 = 0; - - sh7091.SCIF.SCSPTR2 = 0; - sh7091.SCIF.SCLSR2 = 0; - - sh7091.SCIF.SCSCR2 = SCSCR2__TE | SCSCR2__RE; -} - -inline void serial_char(const char c) -{ - // wait for transmit fifo to become empty - while ((sh7091.SCIF.SCFSR2 & SCFSR2__TDFE) == 0); - - for (int i = 0; i < 100000; i++) { - asm volatile ("nop;"); - } - - sh7091.SCIF.SCFTDR2 = static_cast(c); -} - -void serial_string(const char * s) -{ - while (*s != '\0') { - serial_char(*s++); - } -} +#include "macaw.hpp" /* must be aligned to 32-bytes for DMA transfer */ // the aligned(32) attribute does not actually align to 32 bytes; gcc is the best compiler. @@ -69,54 +31,9 @@ void serial_string(const char * s) // __attribute__((aligned(32))) uint32_t _scene[((32 * 6) + 32) / 4]; -template -T * align_32byte(T * mem) -{ - return reinterpret_cast((((reinterpret_cast(mem) + 31) & ~31))); -} - -void serial_int32(const uint32_t n) -{ - char num_buf[9]; - string::hex(num_buf, 8, n); - num_buf[8] = 0; - serial_string("0x"); - serial_string(num_buf); - serial_string("\n"); -} - -void serial_int8(const uint8_t n) -{ - char num_buf[3]; - string::hex(num_buf, 2, n); - num_buf[2] = 0; - serial_string("0x"); - serial_string(num_buf); - serial_string("\n"); -} - 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(); @@ -128,9 +45,6 @@ bool maple_test() //maple_init_device_request(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'); @@ -154,18 +68,8 @@ bool maple_test() return !(data_format->data.digital_button & ft0::data_transfer::digital_button::a); } -extern "C" void main() { - cache_init(); - - // clear BSS - uint32_t * start = &__bss_link_start; - uint32_t * end = &__bss_link_end; - while (start < end) { - *start++ = 0; - } - //serial(); vga(); diff --git a/maple/maple.cpp b/maple/maple.cpp index a0762aa..9a7e5c3 100644 --- a/maple/maple.cpp +++ b/maple/maple.cpp @@ -1,27 +1,29 @@ #include #include -#include "../sh7091.h" -#include "../sh7091_bits.h" -#include "../systembus.h" -#include "../systembus_bits.h" +#include "../sh7091.hpp" +#include "../sh7091_bits.hpp" +#include "../systembus.hpp" +#include "../systembus_bits.hpp" -#include "maple_bits.h" -#include "maple_host_bits.h" -#include "maple_bus_commands.h" -#include "maple.h" +#include "maple_bits.hpp" +#include "maple_bus_bits.hpp" +#include "maple_bus_commands.hpp" +#include "maple.hpp" -void maple_init_host_command(uint32_t * buf, uint32_t * receive_address, uint8_t command_code, uint8_t data_size) +namespace maple { + +void init_host_command(uint32_t * buf, uint32_t * receive_buf, uint8_t command_code, uint8_t data_size) { // this function does not care about the template instantiation of - // maple_host_command--data_fields is not manipulated here. - auto host_command = reinterpret_cast *>(buf); + // host_command--data_fields is not manipulated here. + 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->receive_data_storage_address = reinterpret_cast(receive_buf) & 0x1fff'ffff; host_command->bus_data.command_code = command_code; host_command->bus_data.destination_ap = ap::de::expansion_device | ap::port_select::a | ap::lm_bus::_0; @@ -29,54 +31,47 @@ void maple_init_host_command(uint32_t * buf, uint32_t * receive_address, uint8_t host_command->bus_data.data_size = data_size / 4; } -void maple_init_device_request(uint32_t * buf, uint32_t * receive_address) +void init_device_request(uint32_t * buf, uint32_t * receive_buf) { - maple_init_host_command(buf, receive_address, device_request::command_code, (sizeof (struct device_request::data_fields))); + init_host_command(buf, receive_buf, device_request::command_code, (sizeof (struct device_request::data_fields))); } -void maple_init_get_condition(uint32_t * buf, uint32_t * receive_address) +void init_get_condition(uint32_t * buf, uint32_t * receive_buf) { - maple_init_host_command(buf, receive_address, get_condition::command_code, (sizeof (struct get_condition::data_fields))); + init_host_command(buf, receive_buf, get_condition::command_code, (sizeof (struct get_condition::data_fields))); - auto host_command = reinterpret_cast *>(buf); + auto host_command = reinterpret_cast *>(buf); - auto& function_type = host_command->bus_data.data_fields.function_type; + auto& fields = host_command->bus_data.data_fields; // controller function type - function_type[0] = 0x00; - function_type[1] = 0x00; - function_type[2] = 0x00; - function_type[3] = 0x01; + fields.function_type = std::byteswap(function_type::controller); } -void maple_init_block_write(uint32_t * buf, uint32_t * receive_address, uint32_t * data) +void init_block_write(uint32_t * buf, uint32_t * receive_buf, uint32_t * data) { - maple_init_host_command(buf, receive_address, block_write::command_code, (sizeof (struct block_write::data_fields))); + init_host_command(buf, receive_buf, block_write::command_code, (sizeof (struct block_write::data_fields))); - auto host_command = reinterpret_cast> *>(buf); + 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; + fields.function_type = std::byteswap(function_type::bw_lcd); // lcd number 0 (1 total lcd) - fields.pt[0] = 0; + fields.pt = 0; // phase 0 (from 0 to 3) - fields.phase[0] = 0; + fields.phase = 0; // plane 0 (2 total levels of gradation) - fields.block_no[0] = 0x00; - fields.block_no[1] = 0x00; + fields.block_no = std::byteswap(0x0000); for (uint32_t i = 0; i < (192 / 4); i++) { fields.written_data[i] = data[i]; } } -void maple_dma_start(uint32_t * command_buf) +void 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 */ @@ -113,3 +108,5 @@ void maple_dma_start(uint32_t * command_buf) while ((system.ISTNRM & ISTNRM__END_OF_DMA_MAPLE_DMA) == 0); system.ISTNRM = ISTNRM__END_OF_DMA_MAPLE_DMA; } + +} diff --git a/maple/maple.h b/maple/maple.h deleted file mode 100644 index 621542e..0000000 --- a/maple/maple.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#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/maple/maple.hpp b/maple/maple.hpp new file mode 100644 index 0000000..9450fd3 --- /dev/null +++ b/maple/maple.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include + +namespace maple { + +template +struct 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 init_host_command(uint32_t * command_buf, uint32_t * receive_buf); +void init_device_request(uint32_t * command_buf, uint32_t * receive_buf); +void init_get_condition(uint32_t * command_buf, uint32_t * receive_buf); +void init_block_write(uint32_t * command_buf, uint32_t * receive_buf, uint32_t * data); +void dma_start(uint32_t * command_buf); + +} + diff --git a/maple/maple_bits.h b/maple/maple_bits.hpp similarity index 98% rename from maple/maple_bits.h rename to maple/maple_bits.hpp index 860786a..95b7fa4 100644 --- a/maple/maple_bits.h +++ b/maple/maple_bits.hpp @@ -1,6 +1,6 @@ #include -#include "../float_uint32.h" +#include "../float_uint32.hpp" namespace mdstar { constexpr uint32_t table_address(uint32_t num) { return (num & 0xfffffe0) << 0; } diff --git a/maple/maple_host_bits.h b/maple/maple_bus_bits.hpp similarity index 69% rename from maple/maple_host_bits.h rename to maple/maple_bus_bits.hpp index 1949632..85c2980 100644 --- a/maple/maple_host_bits.h +++ b/maple/maple_bus_bits.hpp @@ -1,6 +1,6 @@ #include -#include "../float_uint32.h" +#include "../float_uint32.hpp" namespace host_instruction { constexpr uint32_t end_flag = 1 << 31; @@ -46,3 +46,18 @@ namespace ap { } } +namespace function_type { + constexpr uint32_t camera = 1 << 11; + constexpr uint32_t exchange_media = 1 << 10; + constexpr uint32_t pointing = 1 << 9; + constexpr uint32_t vibration = 1 << 8; + constexpr uint32_t light_gun = 1 << 7; + constexpr uint32_t keyboard = 1 << 6; + constexpr uint32_t ar_gun = 1 << 5; + constexpr uint32_t audio_input = 1 << 4; + constexpr uint32_t timer = 1 << 3; + constexpr uint32_t bw_lcd = 1 << 2; + constexpr uint32_t storage = 1 << 1; + constexpr uint32_t controller = 1 << 0; +} + diff --git a/maple/maple_bus_commands.h b/maple/maple_bus_commands.hpp similarity index 79% rename from maple/maple_bus_commands.h rename to maple/maple_bus_commands.hpp index 68b90fc..560291e 100644 --- a/maple/maple_bus_commands.h +++ b/maple/maple_bus_commands.hpp @@ -33,12 +33,12 @@ namespace device_status { struct data_fields { uint8_t device_id[16]; - uint8_t destination_code[1]; - uint8_t connection_direction[1]; + uint8_t destination_code; + uint8_t connection_direction; uint8_t product_name[30]; uint8_t license[60]; - uint8_t low_consumption_standby_current[2]; - uint8_t maximum_current_consumption[2]; + uint16_t low_consumption_standby_current; + uint16_t maximum_current_consumption; }; static_assert((sizeof (struct data_fields)) == 112); @@ -50,12 +50,12 @@ namespace device_all_status { template struct data_fields { uint8_t device_id[16]; - uint8_t destination_code[1]; - uint8_t connection_direction[1]; + uint8_t destination_code; + uint8_t connection_direction; uint8_t product_name[30]; uint8_t license[60]; - uint8_t low_consumption_standby_current[2]; - uint8_t maximum_current_consumption[2]; + uint16_t low_consumption_standby_current; + uint16_t maximum_current_consumption; T free_device_status; }; @@ -74,7 +74,7 @@ namespace data_transfer { template struct data_fields { - uint8_t function_type[4]; + uint32_t function_type; T data; }; @@ -85,7 +85,7 @@ namespace get_condition { constexpr uint32_t command_code = 0x9; struct data_fields { - uint8_t function_type[4]; + uint32_t function_type; }; static_assert((sizeof (struct data_fields)) == 4); @@ -95,8 +95,8 @@ namespace get_media_info { constexpr uint32_t command_code = 0xa; struct data_fields { - uint8_t function_type[4]; - uint8_t pt[4]; + uint32_t function_type; + uint32_t pt; }; static_assert((sizeof (struct data_fields)) == 8); @@ -106,10 +106,10 @@ namespace block_read { constexpr uint32_t command_code = 0xb; struct data_fields { - uint8_t function_type[4]; - uint8_t pt[1]; - uint8_t phase[1]; - uint8_t block_no[2]; + uint32_t function_type; + uint8_t pt; + uint8_t phase; + uint16_t block_no; }; static_assert((sizeof (struct data_fields)) == 8); @@ -120,10 +120,10 @@ namespace block_write { template struct data_fields { - uint8_t function_type[4]; - uint8_t pt[1]; - uint8_t phase[1]; - uint8_t block_no[2]; + uint32_t function_type; + uint8_t pt; + uint8_t phase; + uint16_t block_no; T written_data; }; @@ -134,10 +134,10 @@ namespace get_last_error { constexpr uint32_t command_code = 0xd; struct data_fields { - uint8_t function_type[4]; - uint8_t pt[1]; - uint8_t phase[1]; - uint8_t block_no[2]; + uint32_t function_type; + uint8_t pt; + uint8_t phase; + uint16_t block_no; }; static_assert((sizeof (struct data_fields)) == 8); @@ -148,7 +148,7 @@ namespace set_condition { template struct data_fields { - uint8_t function_type[4]; + uint32_t function_type; T write_in_data; }; @@ -160,7 +160,7 @@ namespace ft4_control { template struct data_fields { - uint8_t function_type[4]; + uint32_t function_type; T ft4_data; }; @@ -172,7 +172,7 @@ namespace ar_control { template struct data_fields { - uint8_t function_type[4]; + uint32_t function_type; T data; }; @@ -204,7 +204,7 @@ namespace file_error { constexpr uint32_t command_code = 0xfb; struct data_fields { - uint8_t function_error_code[4]; + uint32_t function_error_code; }; static_assert((sizeof (struct data_fields)) == 4); @@ -214,7 +214,7 @@ namespace lcd_error { constexpr uint32_t command_code = 0xfa; struct data_fields { - uint8_t function_error_code[4]; + uint32_t function_error_code; }; static_assert((sizeof (struct data_fields)) == 4); @@ -224,7 +224,7 @@ namespace ar_error { constexpr uint32_t command_code = 0xf9; struct data_fields { - uint8_t function_error_code[4]; + uint32_t function_error_code; }; static_assert((sizeof (struct data_fields)) == 4); diff --git a/maple/maple_bus_ft0.h b/maple/maple_bus_ft0.hpp similarity index 100% rename from maple/maple_bus_ft0.h rename to maple/maple_bus_ft0.hpp diff --git a/memorymap.h b/memorymap.hpp similarity index 97% rename from memorymap.h rename to memorymap.hpp index fed8642..80ce5eb 100644 --- a/memorymap.h +++ b/memorymap.hpp @@ -1,4 +1,4 @@ -#include +#include extern volatile uint32_t system_boot_rom[0x200000] __asm("system_boot_rom"); extern volatile uint32_t aica_wave_memory[0x200000] __asm("aica_wave_memory"); diff --git a/regs/gen/core_bits.py b/regs/gen/core_bits.py index 4d06746..aca89c1 100644 --- a/regs/gen/core_bits.py +++ b/regs/gen/core_bits.py @@ -36,7 +36,7 @@ def aggregate_enums(aggregated_rows): def assert_unique_ordered(bits): nonlocal all_bits assert all(bit not in all_bits for bit in bits), bits - assert max(all_bits, default=32) > max(bits) + assert max(all_bits, default=32) > max(bits), (all_bits, bits) all_bits |= bits for row in aggregated_rows: @@ -206,7 +206,7 @@ def render_registers(registers): def header(): yield "#include " yield "" - yield '#include "../float_uint32.h"' + yield '#include "../float_uint32.hpp"' yield "" if __name__ == "__main__": diff --git a/regs/gen/maple_commands.py b/regs/gen/maple_commands.py index 6429bb1..e31e634 100644 --- a/regs/gen/maple_commands.py +++ b/regs/gen/maple_commands.py @@ -34,7 +34,11 @@ def command_namespace(namespace: CommandNamespace, for field_name, field_size in data_fields: const, var = field_size if var is None: - yield f"uint8_t {field_name}[{const}];" + if const in {1, 2, 4}: + bits = const * 8 + yield f"uint{bits}_t {field_name};" + else: + yield f"uint8_t {field_name}[{const}];" elif const == 0: assert var == "n" yield f"T {field_name};" diff --git a/regs/gen/memorymap.py b/regs/gen/memorymap.py index 8540835..ec88a6f 100644 --- a/regs/gen/memorymap.py +++ b/regs/gen/memorymap.py @@ -5,7 +5,7 @@ from sh7091 import read_input from generate import renderer def includes(): - yield "#include " + yield "#include " yield "" def process_rows(rows): diff --git a/regs/gen/sh7091.py b/regs/gen/sh7091.py index c416f61..63f88a6 100644 --- a/regs/gen/sh7091.py +++ b/regs/gen/sh7091.py @@ -145,10 +145,10 @@ def blocks(rows): yield 'extern struct sh7091_reg sh7091 __asm("sh7091");' def headers(): - yield "#include " - yield "#include " + yield "#include " + yield "#include " yield "" - yield '#include "type.h"' + yield '#include "type.hpp"' yield "" if __name__ == "__main__": diff --git a/regs/maple_bus_bits.csv b/regs/maple_bus_bits.csv new file mode 100644 index 0000000..029a65e --- /dev/null +++ b/regs/maple_bus_bits.csv @@ -0,0 +1,43 @@ +"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",, +,,,,,, +"function_type",,11,"camera",1,, +"function_type",,10,"exchange_media",1,, +"function_type",,9,"pointing",1,, +"function_type",,8,"vibration",1,, +"function_type",,7,"light_gun",1,, +"function_type",,6,"keyboard",1,, +"function_type",,5,"ar_gun",1,, +"function_type",,4,"audio_input",1,, +"function_type",,3,"timer",1,, +"function_type",,2,"bw_lcd",1,, +"function_type",,1,"storage",1,, +"function_type",,0,"controller",1,, diff --git a/regs/maple_bus_bits.ods b/regs/maple_bus_bits.ods new file mode 100644 index 0000000..16322fc Binary files /dev/null and b/regs/maple_bus_bits.ods differ diff --git a/rgb.cpp b/rgb.cpp index e7f34d4..accf545 100644 --- a/rgb.cpp +++ b/rgb.cpp @@ -1,4 +1,4 @@ -#include "rgb.h" +#include "rgb.hpp" struct rgb hsv_to_rgb(struct hsv hsv) { diff --git a/rgb.h b/rgb.hpp similarity index 100% rename from rgb.h rename to rgb.hpp diff --git a/runtime.cpp b/runtime.cpp new file mode 100644 index 0000000..bdd69a5 --- /dev/null +++ b/runtime.cpp @@ -0,0 +1,27 @@ +#include + +#include "cache.hpp" + +extern uint32_t __bss_link_start __asm("__bss_link_start"); +extern uint32_t __bss_link_end __asm("__bss_link_end"); + +extern void main(); + +extern "C" +void runtime_init() +__attribute__((section(".text.startup.runtime_init"))); + +extern "C" +void runtime_init() +{ + // clear BSS + uint32_t * start = &__bss_link_start; + uint32_t * end = &__bss_link_end; + while (start < end) { + *start++ = 0; + } + + cache::init(); + + main(); +} diff --git a/scene.cpp b/scene.cpp index 4896bad..a9a5d6d 100644 --- a/scene.cpp +++ b/scene.cpp @@ -1,9 +1,9 @@ #include #include -#include "holly/ta_parameter.h" +#include "holly/ta_parameter.hpp" -#include "holly/texture_memory_alloc.h" +#include "holly/texture_memory_alloc.hpp" /* -0.5,-0.5 0.5,-0.5 @@ -80,8 +80,6 @@ union ta_parameter { struct global_end_of_list global_end_of_list; }; -extern void serial_string(const char * s); - uint32_t scene_transform(uint32_t * _scene) { ta_parameter * scene = reinterpret_cast(&_scene[0]); diff --git a/scene.h b/scene.hpp similarity index 100% rename from scene.h rename to scene.hpp diff --git a/serial.cpp b/serial.cpp new file mode 100644 index 0000000..ba028bc --- /dev/null +++ b/serial.cpp @@ -0,0 +1,61 @@ +#include + +#include "sh7091.hpp" +#include "sh7091_bits.hpp" + +#include "string.hpp" + +namespace serial { + +void init() +{ + sh7091.SCIF.SCSCR2 = 0; + sh7091.SCIF.SCSMR2 = 0; + sh7091.SCIF.SCBRR2 = 1; // 520833.3 + + sh7091.SCIF.SCFCR2 = SCFCR2__TFRST | SCFCR2__RFRST; + // tx/rx trigger on 1 byte + sh7091.SCIF.SCFCR2 = 0; + + sh7091.SCIF.SCSPTR2 = 0; + sh7091.SCIF.SCLSR2 = 0; + + sh7091.SCIF.SCSCR2 = SCSCR2__TE | SCSCR2__RE; +} + +void character(const char c) +{ + // wait for transmit fifo to become empty + while ((sh7091.SCIF.SCFSR2 & SCFSR2__TDFE) == 0); + + for (int i = 0; i < 100000; i++) { + asm volatile ("nop;"); + } + + sh7091.SCIF.SCFTDR2 = static_cast(c); +} + +void string(const char * s) +{ + while (*s != '\0') { + character(*s++); + } +} + +template +void integer(const T n) +{ + constexpr uint32_t length = (sizeof (T)) * 2; + char num_buf[length + 1]; + string::hex(num_buf, length, n); + num_buf[length] = 0; + string("0x"); + string(num_buf); + string("\n"); +} + +template void integer(uint32_t param); +template void integer(uint16_t param); +template void integer(uint8_t param); + +} diff --git a/serial.hpp b/serial.hpp new file mode 100644 index 0000000..add72ea --- /dev/null +++ b/serial.hpp @@ -0,0 +1,12 @@ +namespace serial { + +void init(); + +void character(const char c); + +void string(const char * s); + +template +void integer(const T n); + +} diff --git a/sh7091.h b/sh7091.hpp similarity index 99% rename from sh7091.h rename to sh7091.hpp index 039e71a..0eb68ba 100644 --- a/sh7091.h +++ b/sh7091.hpp @@ -1,7 +1,7 @@ -#include -#include +#include +#include -#include "type.h" +#include "type.hpp" struct ccn_reg { reg32 PTEH; /* Page table entry high register */ diff --git a/sh7091_bits.h b/sh7091_bits.hpp similarity index 100% rename from sh7091_bits.h rename to sh7091_bits.hpp diff --git a/start.s b/start.s index b4e5b23..2268c9b 100644 --- a/start.s +++ b/start.s @@ -10,8 +10,8 @@ _start: or r1,r0 ldc r0,sr - /* jump to main */ - mov.l main_ptr,r0 + /* jump to runtime_init */ + mov.l runtime_init_ptr,r0 jmp @r0 nop @@ -20,5 +20,5 @@ p1ram_end_ptr: .long __p1ram_end imask_all: .long 0xf0 -main_ptr: - .long _main +runtime_init_ptr: + .long _runtime_init diff --git a/storequeue.cpp b/storequeue.cpp index e3d05ed..a5cfdda 100644 --- a/storequeue.cpp +++ b/storequeue.cpp @@ -1,5 +1,5 @@ -#include "sh7091.h" -#include "memorymap.h" +#include "sh7091.hpp" +#include "memorymap.hpp" void sq_transfer_32byte(volatile void * dst) { diff --git a/storequeue.h b/storequeue.hpp similarity index 100% rename from storequeue.h rename to storequeue.hpp diff --git a/string.h b/string.hpp similarity index 100% rename from string.h rename to string.hpp diff --git a/systembus.h b/systembus.hpp similarity index 99% rename from systembus.h rename to systembus.hpp index 7f30197..f67dcda 100644 --- a/systembus.h +++ b/systembus.hpp @@ -1,7 +1,7 @@ -#include -#include +#include +#include -#include "type.h" +#include "type.hpp" struct system_reg { reg32 C2DSTAT; /* CH2-DMA destination address */ diff --git a/systembus_bits.h b/systembus_bits.hpp similarity index 100% rename from systembus_bits.h rename to systembus_bits.hpp diff --git a/test.c b/test.c index 96b70a2..30c7e68 100644 --- a/test.c +++ b/test.c @@ -1,9 +1,9 @@ -#include "type.h" +#include "type.hpp" -#include "rgb.h" -#include "vga.h" -#include "systembus.h" -#include "holly.h" +#include "rgb.hpp" +#include "vga.hpp" +#include "systembus.hpp" +#include "holly.hpp" void *memcpy(void *restrict dest, const void *restrict src, size_t n) { diff --git a/type.h b/type.hpp similarity index 85% rename from type.h rename to type.hpp index bc79def..fad568b 100644 --- a/type.h +++ b/type.hpp @@ -1,5 +1,7 @@ -#include -#include +#pragma once + +#include +#include #ifndef __cplusplus #ifndef static_assert diff --git a/vga.cpp b/vga.cpp index aaaa3e7..efb8254 100644 --- a/vga.cpp +++ b/vga.cpp @@ -1,14 +1,14 @@ -#include +#include -#include "sh7091.h" -#include "sh7091_bits.h" -#include "holly.h" -#include "holly/core_bits.h" -#include "aica.h" -#include "memorymap.h" +#include "sh7091.hpp" +#include "sh7091_bits.hpp" +#include "holly.hpp" +#include "holly/core_bits.hpp" +#include "aica.hpp" +#include "memorymap.hpp" -#include "vga.h" -#include "rgb.h" +#include "vga.hpp" +#include "rgb.hpp" uint32_t get_cable_type() { @@ -144,7 +144,7 @@ void vga() holly.SOFTRESET = 0; } -void fill_framebuffer() +void vga_fill_framebuffer() { volatile uint16_t * vram = reinterpret_cast(texture_memory); for (int y = 0; y < 480; y++) { @@ -154,6 +154,4 @@ void fill_framebuffer() vram[y * 640 + x] = ((rgb.r >> 3) << 11) | ((rgb.g >> 2) << 5) | ((rgb.b >> 3) << 0); } } - vram[0] = 0xf0ff; - vram[10] = 0xf0ff; } diff --git a/vga.h b/vga.hpp similarity index 68% rename from vga.h rename to vga.hpp index 3555293..41061b7 100644 --- a/vga.h +++ b/vga.hpp @@ -3,3 +3,4 @@ void vga(); void v_sync_in(); void v_sync_out(); +void vga_fill_framebuffer();