diff --git a/1bpp.py b/1bpp.py new file mode 100644 index 0000000..1d00cca --- /dev/null +++ b/1bpp.py @@ -0,0 +1,31 @@ +import sys + +width = 640 +height = 480 + +with open(sys.argv[1], 'rb') as f: + b = f.read() + assert len(b) == width * height, len(b) + +buf = [] + +for i in range(len(b) // 8): + ix = i * 8 + px = b[ix:ix + 8] + assert all(p in {0, 1} for p in px) + out = ( + (px[0] << 7) + | (px[1] << 6) + | (px[2] << 5) + | (px[3] << 4) + | (px[4] << 3) + | (px[5] << 2) + | (px[6] << 1) + | (px[7] << 0) + ) + buf.append(out) + +assert len(buf) == width * height // 8 + +with open(sys.argv[2], 'wb') as f: + f.write(bytes(buf)) diff --git a/Makefile b/Makefile index 20c0f6e..58af89d 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ MAIN_OBJ = \ holly/region_array.o \ holly/ta_fifo_polygon_converter.o \ holly/core.o \ - maple.o \ + maple/maple.o \ scene.o \ macaw.data.o \ $(LIBGCC) diff --git a/holly/float_uint32.h b/float_uint32.h similarity index 100% rename from holly/float_uint32.h rename to float_uint32.h diff --git a/holly/core.cpp b/holly/core.cpp index 5ef0b97..8aa531e 100644 --- a/holly/core.cpp +++ b/holly/core.cpp @@ -1,4 +1,4 @@ -#include "float_uint32.h" +#include "../float_uint32.h" #include "core_bits.h" #include "../holly.h" #include "../memorymap.h" diff --git a/holly/core_bits.h b/holly/core_bits.h index 5761bde..772da55 100644 --- a/holly/core_bits.h +++ b/holly/core_bits.h @@ -1,6 +1,6 @@ #include -#include "float_uint32.h" +#include "../float_uint32.h" namespace id { constexpr uint32_t device_id(uint32_t reg) { return (reg >> 16) & 0xffff; } diff --git a/holly/ta_bits.h b/holly/ta_bits.h index 40d84d0..ce28ee6 100644 --- a/holly/ta_bits.h +++ b/holly/ta_bits.h @@ -1,6 +1,6 @@ #include -#include "float_uint32.h" +#include "../float_uint32.h" namespace ta_ol_base { constexpr uint32_t base_address(uint32_t num) { return (num & 0xffffe0) << 0; } diff --git a/holly/ta_parameter.h b/holly/ta_parameter.h index c304c2e..963c33e 100644 --- a/holly/ta_parameter.h +++ b/holly/ta_parameter.h @@ -1,7 +1,7 @@ #include #include -#include "float_uint32.h" +#include "../float_uint32.h" #include "isp_tsp.h" namespace para_control { diff --git a/main.cpp b/main.cpp index 800f457..d3dd88e 100644 --- a/main.cpp +++ b/main.cpp @@ -9,8 +9,8 @@ #include "holly/core_bits.h" #include "holly/ta_fifo_polygon_converter.h" #include "systembus.h" -#include "maple.h" -#include "maple_bits.h" +#include "maple/maple.h" +#include "maple/maple_bits.h" #include "holly/texture_memory_alloc.h" diff --git a/maple.cpp b/maple/maple.cpp similarity index 71% rename from maple.cpp rename to maple/maple.cpp index a8cb9c6..77fb592 100644 --- a/maple.cpp +++ b/maple/maple.cpp @@ -1,12 +1,13 @@ #include #include -#include "sh7091.h" -#include "sh7091_bits.h" -#include "systembus.h" -#include "systembus_bits.h" -#include "maple_bits.h" +#include "../sh7091.h" +#include "../sh7091_bits.h" +#include "../systembus.h" +#include "../systembus_bits.h" +#include "maple_bits.h" +#include "maple_bus_commands.h" #include "maple.h" #define AP__PO__A (0b00 << 6) @@ -30,32 +31,31 @@ #define HOST_INSTRUCTION__PORT_SELECT__D (0b11 << 16) #define HOST_INSTRUCTION__TRANSFER_LENGTH(n) (((n) & 0xff) << 0) -template +template struct maple_host_command { uint32_t host_instruction; uint32_t receive_data_storage_address; - uint32_t protocol_data[N]; + uint8_t command_code; + uint8_t destination_ap; + uint8_t source_ap; + uint8_t data_size; + T data_fields; }; void maple_init_host_command(uint32_t * buf, uint32_t * receive_address) { - auto command = reinterpret_cast *>(buf); + auto host_command = reinterpret_cast *>(buf); - 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 - command->receive_data_storage_address = reinterpret_cast(receive_address); + host_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; - // maple bus is big endian - command->protocol_data[0] = std::byteswap( (command_code << 24) - | (destination_ap << 16) - | (source_ap << 8) - | (data_size << 0)); + 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; } void maple_dma_start(uint32_t * command_buf) diff --git a/maple.h b/maple/maple.h similarity index 100% rename from maple.h rename to maple/maple.h diff --git a/maple_bits.h b/maple/maple_bits.h similarity index 98% rename from maple_bits.h rename to maple/maple_bits.h index 9343e3d..860786a 100644 --- a/maple_bits.h +++ b/maple/maple_bits.h @@ -1,6 +1,6 @@ #include -#include "holly/float_uint32.h" +#include "../float_uint32.h" namespace mdstar { constexpr uint32_t table_address(uint32_t num) { return (num & 0xfffffe0) << 0; } @@ -31,12 +31,12 @@ namespace mdst { 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; } } @@ -75,4 +75,3 @@ namespace mrxdad { namespace mrxdbd { constexpr uint32_t rxd_base_address(uint32_t reg) { return (reg >> 0) & 0x1fffffff; } } - diff --git a/maple/maple_bus_commands.h b/maple/maple_bus_commands.h new file mode 100644 index 0000000..259b86c --- /dev/null +++ b/maple/maple_bus_commands.h @@ -0,0 +1,231 @@ +#include + +namespace device_request { + constexpr uint32_t command_code = 0x1; + + struct data_fields { + }; +} + +namespace all_status_request { + constexpr uint32_t command_code = 0x2; + + struct data_fields { + }; +} + +namespace device_reset { + constexpr uint32_t command_code = 0x3; + + struct data_fields { + }; +} + +namespace device_kill { + constexpr uint32_t command_code = 0x4; + + struct data_fields { + }; +} + +namespace device_status { + constexpr uint32_t command_code = 0x5; + + struct data_fields { + uint8_t device_id[16]; + uint8_t destination_code[1]; + uint8_t connection_direction[1]; + uint8_t product_name[30]; + uint8_t license[60]; + uint8_t low_consumption_standby_current[2]; + uint8_t maximum_current_consumption[2]; + }; + + static_assert((sizeof (struct data_fields)) == 112); +} + +namespace device_all_status { + constexpr uint32_t command_code = 0x6; + + template + struct data_fields { + uint8_t device_id[16]; + uint8_t destination_code[1]; + uint8_t connection_direction[1]; + uint8_t product_name[30]; + uint8_t license[60]; + uint8_t low_consumption_standby_current[2]; + uint8_t maximum_current_consumption[2]; + uint8_t free_device_status[N]; + }; + + static_assert((sizeof (struct data_fields<0>)) == 112); +} + +namespace device_reply { + constexpr uint32_t command_code = 0x7; + + struct data_fields { + }; +} + +namespace data_transfer { + constexpr uint32_t command_code = 0x8; + + template + struct data_fields { + uint8_t data[N]; + }; + + static_assert((sizeof (struct data_fields<0>)) == 0); +} + +namespace get_condition { + constexpr uint32_t command_code = 0x9; + + struct data_fields { + uint8_t function_type[4]; + }; + + static_assert((sizeof (struct data_fields)) == 4); +} + +namespace get_media_info { + constexpr uint32_t command_code = 0xa; + + struct data_fields { + uint8_t function_type[4]; + uint8_t pt[4]; + }; + + static_assert((sizeof (struct data_fields)) == 8); +} + +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]; + }; + + static_assert((sizeof (struct data_fields)) == 8); +} + +namespace block_write { + constexpr uint32_t command_code = 0xc; + + template + struct data_fields { + uint8_t function_type[4]; + uint8_t pt[1]; + uint8_t phase[1]; + uint8_t block_no[2]; + uint8_t written_data[N]; + }; + + static_assert((sizeof (struct data_fields<0>)) == 8); +} + +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]; + }; + + static_assert((sizeof (struct data_fields)) == 8); +} + +namespace set_condition { + constexpr uint32_t command_code = 0xe; + + template + struct data_fields { + uint8_t function_type[4]; + uint8_t write_in_data[N]; + }; + + static_assert((sizeof (struct data_fields<0>)) == 4); +} + +namespace ft4_control { + constexpr uint32_t command_code = 0xf; + + template + struct data_fields { + uint8_t function_type[4]; + uint8_t ft4_data[N]; + }; + + static_assert((sizeof (struct data_fields<0>)) == 4); +} + +namespace ar_control { + constexpr uint32_t command_code = 0x10; + + template + struct data_fields { + uint8_t function_type[4]; + uint8_t data[N]; + }; + + static_assert((sizeof (struct data_fields<0>)) == 4); +} + +namespace function_type_unknown { + constexpr uint32_t command_code = 0xfe; + + struct data_fields { + }; +} + +namespace command_unknown { + constexpr uint32_t command_code = 0xfd; + + struct data_fields { + }; +} + +namespace transmit_again { + constexpr uint32_t command_code = 0xfc; + + struct data_fields { + }; +} + +namespace file_error { + constexpr uint32_t command_code = 0xfb; + + struct data_fields { + uint8_t function_error_code[4]; + }; + + static_assert((sizeof (struct data_fields)) == 4); +} + +namespace lcd_error { + constexpr uint32_t command_code = 0xfa; + + struct data_fields { + uint8_t function_error_code[4]; + }; + + static_assert((sizeof (struct data_fields)) == 4); +} + +namespace ar_error { + constexpr uint32_t command_code = 0xf9; + + struct data_fields { + uint8_t function_error_code[4]; + }; + + static_assert((sizeof (struct data_fields)) == 4); +} + diff --git a/maple_bus_commands.h b/maple_bus_commands.h index fce4be1..18c41cc 100644 --- a/maple_bus_commands.h +++ b/maple_bus_commands.h @@ -5,24 +5,32 @@ namespace device_request { constexpr uint32_t command_code = 0x1; + struct data_fields { + }; } namespace all_status_request { constexpr uint32_t command_code = 0x2; + struct data_fields { + }; } namespace device_reset { constexpr uint32_t command_code = 0x3; + struct data_fields { + }; } namespace device_kill { constexpr uint32_t command_code = 0x4; + struct data_fields { + }; } namespace device_status { constexpr uint32_t command_code = 0x5; - struct data_fields { + uint8_t device_id[16]; uint8_t destination_code[1]; uint8_t connection_direction[1]; @@ -31,15 +39,15 @@ namespace device_status { uint8_t low_consumption_standby_current[2]; uint8_t maximum_current_consumption[2]; }; - + static_assert((sizeof (struct data_fields)) == 112); } namespace device_all_status { constexpr uint32_t command_code = 0x6; - - template struct data_fields { + + template uint8_t device_id[16]; uint8_t destination_code[1]; uint8_t connection_direction[1]; @@ -49,162 +57,169 @@ namespace device_all_status { uint8_t maximum_current_consumption[2]; uint8_t free_device_status[N]; }; - + static_assert((sizeof (struct data_fields<0>)) == 112); } namespace device_reply { constexpr uint32_t command_code = 0x7; + struct data_fields { + }; } namespace data_transfer { constexpr uint32_t command_code = 0x8; - - template struct data_fields { + + template uint8_t data[N]; }; - + static_assert((sizeof (struct data_fields<0>)) == 0); } namespace get_condition { constexpr uint32_t command_code = 0x9; - struct data_fields { + uint8_t function_type[4]; }; - + static_assert((sizeof (struct data_fields)) == 4); } namespace get_media_info { constexpr uint32_t command_code = 0xa; - struct data_fields { + uint8_t function_type[4]; uint8_t pt[4]; }; - + static_assert((sizeof (struct data_fields)) == 8); } 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]; }; - + static_assert((sizeof (struct data_fields)) == 8); } namespace block_write { constexpr uint32_t command_code = 0xc; - - template struct data_fields { + + template uint8_t function_type[4]; uint8_t pt[1]; uint8_t phase[1]; uint8_t block_no[2]; uint8_t written_data[N]; }; - + static_assert((sizeof (struct data_fields<0>)) == 8); } 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]; }; - + static_assert((sizeof (struct data_fields)) == 8); } namespace set_condition { constexpr uint32_t command_code = 0xe; - - template struct data_fields { + + template uint8_t function_type[4]; uint8_t write_in_data[N]; }; - + static_assert((sizeof (struct data_fields<0>)) == 4); } namespace ft4_control { constexpr uint32_t command_code = 0xf; - - template struct data_fields { + + template uint8_t function_type[4]; uint8_t ft4_data[N]; }; - + static_assert((sizeof (struct data_fields<0>)) == 4); } namespace ar_control { constexpr uint32_t command_code = 0x10; - - template struct data_fields { + + template uint8_t function_type[4]; uint8_t data[N]; }; - + static_assert((sizeof (struct data_fields<0>)) == 4); } namespace function_type_unknown { constexpr uint32_t command_code = 0xfe; + struct data_fields { + }; } namespace command_unknown { constexpr uint32_t command_code = 0xfd; + struct data_fields { + }; } namespace transmit_again { constexpr uint32_t command_code = 0xfc; + struct data_fields { + }; } namespace file_error { constexpr uint32_t command_code = 0xfb; - struct data_fields { + uint8_t function_error_code[4]; }; - + static_assert((sizeof (struct data_fields)) == 4); } namespace lcd_error { constexpr uint32_t command_code = 0xfa; - struct data_fields { + uint8_t function_error_code[4]; }; - + static_assert((sizeof (struct data_fields)) == 4); } namespace ar_error { constexpr uint32_t command_code = 0xf9; - struct data_fields { + uint8_t function_error_code[4]; }; - + static_assert((sizeof (struct data_fields)) == 4); } - diff --git a/notes/hamming-framing.txt b/notes/hamming-framing.txt new file mode 100644 index 0000000..84afa04 --- /dev/null +++ b/notes/hamming-framing.txt @@ -0,0 +1,11 @@ +frames: + 0b00 invalid + 0b01 command begin + 0b10 data begin + 0b11 frame end + +commands: + - jump addr + - read addr + - write addr + - speed value diff --git a/maple-notes.txt b/notes/maple.txt similarity index 100% rename from maple-notes.txt rename to notes/maple.txt diff --git a/notes.txt b/notes/ta.txt similarity index 100% rename from notes.txt rename to notes/ta.txt diff --git a/vga-notes.txt b/notes/vga.txt similarity index 100% rename from vga-notes.txt rename to notes/vga.txt diff --git a/regs/gen/core_bits.py b/regs/gen/core_bits.py index 9706524..4d06746 100644 --- a/regs/gen/core_bits.py +++ b/regs/gen/core_bits.py @@ -206,7 +206,7 @@ def render_registers(registers): def header(): yield "#include " yield "" - yield '#include "float_uint32.h"' + yield '#include "../float_uint32.h"' yield "" if __name__ == "__main__": diff --git a/regs/gen/maple_commands.py b/regs/gen/maple_commands.py index d67595a..30dd322 100644 --- a/regs/gen/maple_commands.py +++ b/regs/gen/maple_commands.py @@ -3,7 +3,6 @@ from typing import Union import sys from sh7091 import read_input -from sh7091 import headers from generate import renderer @dataclass @@ -17,15 +16,15 @@ def command_namespace(namespace: CommandNamespace, data_fields: list[tuple[str, tuple[int, str]]]): yield f"namespace {namespace.name} {{" yield f"constexpr uint32_t command_code = {hex(namespace.command_code)};" + yield "" if namespace.data_size == (0, None): assert data_fields == [] - # do nothing + yield "struct data_fields {" + yield "};" else: length, variable = namespace.data_size - yield "" - if variable is not None: assert variable.lower() == "n" yield "template " @@ -149,6 +148,10 @@ def new_aggregator(): return process +def headers(): + yield "#include " + yield "" + input_file = sys.argv[1] rows = read_input(input_file) process = new_aggregator()