diff --git a/common.mk b/common.mk index 098c356..67ae4a0 100644 --- a/common.mk +++ b/common.mk @@ -145,10 +145,10 @@ holly/core_bits.hpp: regs/core_bits.csv regs/gen/core_bits.py holly/holly.hpp: regs/holly.csv regs/gen/holly.py python regs/gen/holly.py $< > $@ -holly/ta_global_parameter.hpp: regs/global_parameter_format.csv regs/gen/ta_parameter_format.py +holly/ta_global_parameter.hpp: regs/global_parameter_format.csv regs/gen/ta_parameter_format.py regs/gen/generic_sparse_struct.py python regs/gen/ta_parameter_format.py $< ta_global_parameter > $@ -holly/ta_vertex_parameter.hpp: regs/vertex_parameter_format.csv regs/gen/ta_parameter_format.py +holly/ta_vertex_parameter.hpp: regs/vertex_parameter_format.csv regs/gen/ta_parameter_format.py regs/gen/generic_sparse_struct.py python regs/gen/ta_parameter_format.py $< ta_vertex_parameter > $@ holly/object_list_data.hpp: regs/object_list.csv regs/gen/core_bits.py @@ -160,6 +160,9 @@ sh7091/sh7091.hpp: regs/sh7091.csv regs/gen/sh7091.py sh7091/sh7091_bits.hpp: regs/sh7091_bits.csv regs/gen/core_bits.py python regs/gen/core_bits.py $< > $@ +gdrom/command_packet_format.hpp: regs/gdrom_command_packet_format.csv regs/gen/gdrom_command_packet_format.py regs/gen/generic_sparse_struct.py + python regs/gen/gdrom_command_packet_format.py $< gdrom_command_packet_format > $@ + clean: find -P \ -regextype posix-egrep \ diff --git a/example/gdrom_test.cpp b/example/gdrom_test.cpp index 21efcd1..be00070 100644 --- a/example/gdrom_test.cpp +++ b/example/gdrom_test.cpp @@ -1,5 +1,5 @@ -#include "gdrom.hpp" -#include "gdrom_bits.hpp" +#include "gdrom/gdrom.hpp" +#include "gdrom/gdrom_bits.hpp" #include "memorymap.hpp" #include "systembus.hpp" diff --git a/gdrom/command_packet_format.hpp b/gdrom/command_packet_format.hpp new file mode 100644 index 0000000..af47e1e --- /dev/null +++ b/gdrom/command_packet_format.hpp @@ -0,0 +1,577 @@ +#pragma once + +#include +#include + +namespace gdrom_command_packet_format { + struct test_unit { + uint8_t command_code; + uint8_t _res0; + uint8_t _res1; + uint8_t _res2; + uint8_t _res3; + uint8_t _res4; + uint8_t _res5; + uint8_t _res6; + uint8_t _res7; + uint8_t _res8; + uint8_t _res9; + uint8_t _res10; + + test_unit() + : command_code(0x0) + , _res0(0) + , _res1(0) + , _res2(0) + , _res3(0) + , _res4(0) + , _res5(0) + , _res6(0) + , _res7(0) + , _res8(0) + , _res9(0) + , _res10(0) + { } + }; + static_assert((sizeof (test_unit)) == 12); + static_assert((offsetof (struct test_unit, command_code)) == 0x00); + static_assert((offsetof (struct test_unit, _res0)) == 0x01); + static_assert((offsetof (struct test_unit, _res1)) == 0x02); + static_assert((offsetof (struct test_unit, _res2)) == 0x03); + static_assert((offsetof (struct test_unit, _res3)) == 0x04); + static_assert((offsetof (struct test_unit, _res4)) == 0x05); + static_assert((offsetof (struct test_unit, _res5)) == 0x06); + static_assert((offsetof (struct test_unit, _res6)) == 0x07); + static_assert((offsetof (struct test_unit, _res7)) == 0x08); + static_assert((offsetof (struct test_unit, _res8)) == 0x09); + static_assert((offsetof (struct test_unit, _res9)) == 0x0a); + static_assert((offsetof (struct test_unit, _res10)) == 0x0b); + + struct req_stat { + uint8_t command_code; + uint8_t _res0; + uint8_t starting_address; + uint8_t _res1; + uint8_t allocation_length; + uint8_t _res2; + uint8_t _res3; + uint8_t _res4; + uint8_t _res5; + uint8_t _res6; + uint8_t _res7; + uint8_t _res8; + + req_stat(const uint8_t starting_address, + const uint8_t allocation_length + ) + : command_code(0x10) + , _res0(0) + , starting_address(starting_address) + , _res1(0) + , allocation_length(allocation_length) + , _res2(0) + , _res3(0) + , _res4(0) + , _res5(0) + , _res6(0) + , _res7(0) + , _res8(0) + { } + }; + static_assert((sizeof (req_stat)) == 12); + static_assert((offsetof (struct req_stat, command_code)) == 0x00); + static_assert((offsetof (struct req_stat, _res0)) == 0x01); + static_assert((offsetof (struct req_stat, starting_address)) == 0x02); + static_assert((offsetof (struct req_stat, _res1)) == 0x03); + static_assert((offsetof (struct req_stat, allocation_length)) == 0x04); + static_assert((offsetof (struct req_stat, _res2)) == 0x05); + static_assert((offsetof (struct req_stat, _res3)) == 0x06); + static_assert((offsetof (struct req_stat, _res4)) == 0x07); + static_assert((offsetof (struct req_stat, _res5)) == 0x08); + static_assert((offsetof (struct req_stat, _res6)) == 0x09); + static_assert((offsetof (struct req_stat, _res7)) == 0x0a); + static_assert((offsetof (struct req_stat, _res8)) == 0x0b); + + struct req_mode { + uint8_t command_code; + uint8_t _res0; + uint8_t starting_address; + uint8_t _res1; + uint8_t allocation_length; + uint8_t _res2; + uint8_t _res3; + uint8_t _res4; + uint8_t _res5; + uint8_t _res6; + uint8_t _res7; + uint8_t _res8; + + req_mode(const uint8_t starting_address, + const uint8_t allocation_length + ) + : command_code(0x11) + , _res0(0) + , starting_address(starting_address) + , _res1(0) + , allocation_length(allocation_length) + , _res2(0) + , _res3(0) + , _res4(0) + , _res5(0) + , _res6(0) + , _res7(0) + , _res8(0) + { } + }; + static_assert((sizeof (req_mode)) == 12); + static_assert((offsetof (struct req_mode, command_code)) == 0x00); + static_assert((offsetof (struct req_mode, _res0)) == 0x01); + static_assert((offsetof (struct req_mode, starting_address)) == 0x02); + static_assert((offsetof (struct req_mode, _res1)) == 0x03); + static_assert((offsetof (struct req_mode, allocation_length)) == 0x04); + static_assert((offsetof (struct req_mode, _res2)) == 0x05); + static_assert((offsetof (struct req_mode, _res3)) == 0x06); + static_assert((offsetof (struct req_mode, _res4)) == 0x07); + static_assert((offsetof (struct req_mode, _res5)) == 0x08); + static_assert((offsetof (struct req_mode, _res6)) == 0x09); + static_assert((offsetof (struct req_mode, _res7)) == 0x0a); + static_assert((offsetof (struct req_mode, _res8)) == 0x0b); + + struct set_mode { + uint8_t command_code; + uint8_t _res0; + uint8_t starting_address; + uint8_t _res1; + uint8_t allocation_length; + uint8_t _res2; + uint8_t _res3; + uint8_t _res4; + uint8_t _res5; + uint8_t _res6; + uint8_t _res7; + uint8_t _res8; + + set_mode(const uint8_t starting_address, + const uint8_t allocation_length + ) + : command_code(0x12) + , _res0(0) + , starting_address(starting_address) + , _res1(0) + , allocation_length(allocation_length) + , _res2(0) + , _res3(0) + , _res4(0) + , _res5(0) + , _res6(0) + , _res7(0) + , _res8(0) + { } + }; + static_assert((sizeof (set_mode)) == 12); + static_assert((offsetof (struct set_mode, command_code)) == 0x00); + static_assert((offsetof (struct set_mode, _res0)) == 0x01); + static_assert((offsetof (struct set_mode, starting_address)) == 0x02); + static_assert((offsetof (struct set_mode, _res1)) == 0x03); + static_assert((offsetof (struct set_mode, allocation_length)) == 0x04); + static_assert((offsetof (struct set_mode, _res2)) == 0x05); + static_assert((offsetof (struct set_mode, _res3)) == 0x06); + static_assert((offsetof (struct set_mode, _res4)) == 0x07); + static_assert((offsetof (struct set_mode, _res5)) == 0x08); + static_assert((offsetof (struct set_mode, _res6)) == 0x09); + static_assert((offsetof (struct set_mode, _res7)) == 0x0a); + static_assert((offsetof (struct set_mode, _res8)) == 0x0b); + + struct req_error { + uint8_t command_code; + uint8_t _res0; + uint8_t _res1; + uint8_t _res2; + uint8_t allocation_length; + uint8_t _res3; + uint8_t _res4; + uint8_t _res5; + uint8_t _res6; + uint8_t _res7; + uint8_t _res8; + uint8_t _res9; + + req_error(const uint8_t allocation_length + ) + : command_code(0x13) + , _res0(0) + , _res1(0) + , _res2(0) + , allocation_length(allocation_length) + , _res3(0) + , _res4(0) + , _res5(0) + , _res6(0) + , _res7(0) + , _res8(0) + , _res9(0) + { } + }; + static_assert((sizeof (req_error)) == 12); + static_assert((offsetof (struct req_error, command_code)) == 0x00); + static_assert((offsetof (struct req_error, _res0)) == 0x01); + static_assert((offsetof (struct req_error, _res1)) == 0x02); + static_assert((offsetof (struct req_error, _res2)) == 0x03); + static_assert((offsetof (struct req_error, allocation_length)) == 0x04); + static_assert((offsetof (struct req_error, _res3)) == 0x05); + static_assert((offsetof (struct req_error, _res4)) == 0x06); + static_assert((offsetof (struct req_error, _res5)) == 0x07); + static_assert((offsetof (struct req_error, _res6)) == 0x08); + static_assert((offsetof (struct req_error, _res7)) == 0x09); + static_assert((offsetof (struct req_error, _res8)) == 0x0a); + static_assert((offsetof (struct req_error, _res9)) == 0x0b); + + struct get_toc { + uint8_t command_code; + uint8_t select; + uint8_t _res0; + uint8_t allocation_length[2]; + uint8_t _res1; + uint8_t _res2; + uint8_t _res3; + uint8_t _res4; + uint8_t _res5; + uint8_t _res6; + uint8_t _res7; + + get_toc(const uint8_t select + ) + : command_code(0x14) + , select(select) + , _res0(0) + , allocation_length() + , _res1(0) + , _res2(0) + , _res3(0) + , _res4(0) + , _res5(0) + , _res6(0) + , _res7(0) + { } + }; + static_assert((sizeof (get_toc)) == 12); + static_assert((offsetof (struct get_toc, command_code)) == 0x00); + static_assert((offsetof (struct get_toc, select)) == 0x01); + static_assert((offsetof (struct get_toc, _res0)) == 0x02); + static_assert((offsetof (struct get_toc, allocation_length)) == 0x03); + static_assert((offsetof (struct get_toc, _res1)) == 0x05); + static_assert((offsetof (struct get_toc, _res2)) == 0x06); + static_assert((offsetof (struct get_toc, _res3)) == 0x07); + static_assert((offsetof (struct get_toc, _res4)) == 0x08); + static_assert((offsetof (struct get_toc, _res5)) == 0x09); + static_assert((offsetof (struct get_toc, _res6)) == 0x0a); + static_assert((offsetof (struct get_toc, _res7)) == 0x0b); + + struct req_ses { + uint8_t command_code; + uint8_t _res0; + uint8_t session_number; + uint8_t _res1; + uint8_t allocation_length; + uint8_t _res2; + uint8_t _res3; + uint8_t _res4; + uint8_t _res5; + uint8_t _res6; + uint8_t _res7; + uint8_t _res8; + + req_ses(const uint8_t session_number, + const uint8_t allocation_length + ) + : command_code(0x15) + , _res0(0) + , session_number(session_number) + , _res1(0) + , allocation_length(allocation_length) + , _res2(0) + , _res3(0) + , _res4(0) + , _res5(0) + , _res6(0) + , _res7(0) + , _res8(0) + { } + }; + static_assert((sizeof (req_ses)) == 12); + static_assert((offsetof (struct req_ses, command_code)) == 0x00); + static_assert((offsetof (struct req_ses, _res0)) == 0x01); + static_assert((offsetof (struct req_ses, session_number)) == 0x02); + static_assert((offsetof (struct req_ses, _res1)) == 0x03); + static_assert((offsetof (struct req_ses, allocation_length)) == 0x04); + static_assert((offsetof (struct req_ses, _res2)) == 0x05); + static_assert((offsetof (struct req_ses, _res3)) == 0x06); + static_assert((offsetof (struct req_ses, _res4)) == 0x07); + static_assert((offsetof (struct req_ses, _res5)) == 0x08); + static_assert((offsetof (struct req_ses, _res6)) == 0x09); + static_assert((offsetof (struct req_ses, _res7)) == 0x0a); + static_assert((offsetof (struct req_ses, _res8)) == 0x0b); + + struct cd_open { + uint8_t command_code; + uint8_t _res0; + uint8_t _res1; + uint8_t _res2; + uint8_t _res3; + uint8_t _res4; + uint8_t _res5; + uint8_t _res6; + uint8_t _res7; + uint8_t _res8; + uint8_t _res9; + uint8_t _res10; + + cd_open() + : command_code(0x16) + , _res0(0) + , _res1(0) + , _res2(0) + , _res3(0) + , _res4(0) + , _res5(0) + , _res6(0) + , _res7(0) + , _res8(0) + , _res9(0) + , _res10(0) + { } + }; + static_assert((sizeof (cd_open)) == 12); + static_assert((offsetof (struct cd_open, command_code)) == 0x00); + static_assert((offsetof (struct cd_open, _res0)) == 0x01); + static_assert((offsetof (struct cd_open, _res1)) == 0x02); + static_assert((offsetof (struct cd_open, _res2)) == 0x03); + static_assert((offsetof (struct cd_open, _res3)) == 0x04); + static_assert((offsetof (struct cd_open, _res4)) == 0x05); + static_assert((offsetof (struct cd_open, _res5)) == 0x06); + static_assert((offsetof (struct cd_open, _res6)) == 0x07); + static_assert((offsetof (struct cd_open, _res7)) == 0x08); + static_assert((offsetof (struct cd_open, _res8)) == 0x09); + static_assert((offsetof (struct cd_open, _res9)) == 0x0a); + static_assert((offsetof (struct cd_open, _res10)) == 0x0b); + + struct cd_play { + uint8_t command_code; + uint8_t parameter_type; + uint8_t starting_point[3]; + uint8_t _res0; + uint8_t repeat_times; + uint8_t _res1; + uint8_t end_point[3]; + uint8_t _res2; + + cd_play(const uint8_t parameter_type, + const uint8_t repeat_times + ) + : command_code(0x20) + , parameter_type(parameter_type) + , starting_point() + , _res0(0) + , repeat_times(repeat_times) + , _res1(0) + , end_point() + , _res2(0) + { } + }; + static_assert((sizeof (cd_play)) == 12); + static_assert((offsetof (struct cd_play, command_code)) == 0x00); + static_assert((offsetof (struct cd_play, parameter_type)) == 0x01); + static_assert((offsetof (struct cd_play, starting_point)) == 0x02); + static_assert((offsetof (struct cd_play, _res0)) == 0x05); + static_assert((offsetof (struct cd_play, repeat_times)) == 0x06); + static_assert((offsetof (struct cd_play, _res1)) == 0x07); + static_assert((offsetof (struct cd_play, end_point)) == 0x08); + static_assert((offsetof (struct cd_play, _res2)) == 0x0b); + + struct cd_seek { + uint8_t command_code; + uint8_t parameter_type; + uint8_t seek_point[3]; + uint8_t _res0; + uint8_t _res1; + uint8_t _res2; + uint8_t _res3; + uint8_t _res4; + uint8_t _res5; + uint8_t _res6; + + cd_seek(const uint8_t parameter_type + ) + : command_code(0x21) + , parameter_type(parameter_type) + , seek_point() + , _res0(0) + , _res1(0) + , _res2(0) + , _res3(0) + , _res4(0) + , _res5(0) + , _res6(0) + { } + }; + static_assert((sizeof (cd_seek)) == 12); + static_assert((offsetof (struct cd_seek, command_code)) == 0x00); + static_assert((offsetof (struct cd_seek, parameter_type)) == 0x01); + static_assert((offsetof (struct cd_seek, seek_point)) == 0x02); + static_assert((offsetof (struct cd_seek, _res0)) == 0x05); + static_assert((offsetof (struct cd_seek, _res1)) == 0x06); + static_assert((offsetof (struct cd_seek, _res2)) == 0x07); + static_assert((offsetof (struct cd_seek, _res3)) == 0x08); + static_assert((offsetof (struct cd_seek, _res4)) == 0x09); + static_assert((offsetof (struct cd_seek, _res5)) == 0x0a); + static_assert((offsetof (struct cd_seek, _res6)) == 0x0b); + + struct cd_scan { + uint8_t command_code; + uint8_t _res0; + uint8_t direction; + uint8_t speed; + uint8_t _res1; + uint8_t _res2; + uint8_t _res3; + uint8_t _res4; + uint8_t _res5; + uint8_t _res6; + uint8_t _res7; + uint8_t _res8; + + cd_scan(const uint8_t direction, + const uint8_t speed + ) + : command_code(0x22) + , _res0(0) + , direction(direction) + , speed(speed) + , _res1(0) + , _res2(0) + , _res3(0) + , _res4(0) + , _res5(0) + , _res6(0) + , _res7(0) + , _res8(0) + { } + }; + static_assert((sizeof (cd_scan)) == 12); + static_assert((offsetof (struct cd_scan, command_code)) == 0x00); + static_assert((offsetof (struct cd_scan, _res0)) == 0x01); + static_assert((offsetof (struct cd_scan, direction)) == 0x02); + static_assert((offsetof (struct cd_scan, speed)) == 0x03); + static_assert((offsetof (struct cd_scan, _res1)) == 0x04); + static_assert((offsetof (struct cd_scan, _res2)) == 0x05); + static_assert((offsetof (struct cd_scan, _res3)) == 0x06); + static_assert((offsetof (struct cd_scan, _res4)) == 0x07); + static_assert((offsetof (struct cd_scan, _res5)) == 0x08); + static_assert((offsetof (struct cd_scan, _res6)) == 0x09); + static_assert((offsetof (struct cd_scan, _res7)) == 0x0a); + static_assert((offsetof (struct cd_scan, _res8)) == 0x0b); + + struct cd_read { + uint8_t command_code; + uint8_t data; + uint8_t starting_address[3]; + uint8_t _res0; + uint8_t _res1; + uint8_t _res2; + uint8_t transfer_length[3]; + uint8_t _res3; + + cd_read(const uint8_t data + ) + : command_code(0x30) + , data(data) + , starting_address() + , _res0(0) + , _res1(0) + , _res2(0) + , transfer_length() + , _res3(0) + { } + }; + static_assert((sizeof (cd_read)) == 12); + static_assert((offsetof (struct cd_read, command_code)) == 0x00); + static_assert((offsetof (struct cd_read, data)) == 0x01); + static_assert((offsetof (struct cd_read, starting_address)) == 0x02); + static_assert((offsetof (struct cd_read, _res0)) == 0x05); + static_assert((offsetof (struct cd_read, _res1)) == 0x06); + static_assert((offsetof (struct cd_read, _res2)) == 0x07); + static_assert((offsetof (struct cd_read, transfer_length)) == 0x08); + static_assert((offsetof (struct cd_read, _res3)) == 0x0b); + + struct cd_read2 { + uint8_t command_code; + uint8_t data; + uint8_t starting_address[3]; + uint8_t _res0; + uint8_t transfer_length[2]; + uint8_t next_address[3]; + uint8_t _res1; + + cd_read2(const uint8_t data + ) + : command_code(0x31) + , data(data) + , starting_address() + , _res0(0) + , transfer_length() + , next_address() + , _res1(0) + { } + }; + static_assert((sizeof (cd_read2)) == 12); + static_assert((offsetof (struct cd_read2, command_code)) == 0x00); + static_assert((offsetof (struct cd_read2, data)) == 0x01); + static_assert((offsetof (struct cd_read2, starting_address)) == 0x02); + static_assert((offsetof (struct cd_read2, _res0)) == 0x05); + static_assert((offsetof (struct cd_read2, transfer_length)) == 0x06); + static_assert((offsetof (struct cd_read2, next_address)) == 0x08); + static_assert((offsetof (struct cd_read2, _res1)) == 0x0b); + + struct cd_scd { + uint8_t command_code; + uint8_t data_format; + uint8_t _res0; + uint8_t allocation_length[2]; + uint8_t _res1; + uint8_t _res2; + uint8_t _res3; + uint8_t _res4; + uint8_t _res5; + uint8_t _res6; + uint8_t _res7; + + cd_scd(const uint8_t data_format + ) + : command_code(0x40) + , data_format(data_format) + , _res0(0) + , allocation_length() + , _res1(0) + , _res2(0) + , _res3(0) + , _res4(0) + , _res5(0) + , _res6(0) + , _res7(0) + { } + }; + static_assert((sizeof (cd_scd)) == 12); + static_assert((offsetof (struct cd_scd, command_code)) == 0x00); + static_assert((offsetof (struct cd_scd, data_format)) == 0x01); + static_assert((offsetof (struct cd_scd, _res0)) == 0x02); + static_assert((offsetof (struct cd_scd, allocation_length)) == 0x03); + static_assert((offsetof (struct cd_scd, _res1)) == 0x05); + static_assert((offsetof (struct cd_scd, _res2)) == 0x06); + static_assert((offsetof (struct cd_scd, _res3)) == 0x07); + static_assert((offsetof (struct cd_scd, _res4)) == 0x08); + static_assert((offsetof (struct cd_scd, _res5)) == 0x09); + static_assert((offsetof (struct cd_scd, _res6)) == 0x0a); + static_assert((offsetof (struct cd_scd, _res7)) == 0x0b); + +} + diff --git a/gdrom.hpp b/gdrom/gdrom.hpp similarity index 100% rename from gdrom.hpp rename to gdrom/gdrom.hpp diff --git a/gdrom_bits.hpp b/gdrom/gdrom_bits.hpp similarity index 100% rename from gdrom_bits.hpp rename to gdrom/gdrom_bits.hpp diff --git a/holly/ta_global_parameter.hpp b/holly/ta_global_parameter.hpp index a1149e3..5ef88e1 100644 --- a/holly/ta_global_parameter.hpp +++ b/holly/ta_global_parameter.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include namespace ta_global_parameter { struct end_of_list { diff --git a/holly/ta_vertex_parameter.hpp b/holly/ta_vertex_parameter.hpp index f2f3bdf..c253d08 100644 --- a/holly/ta_vertex_parameter.hpp +++ b/holly/ta_vertex_parameter.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include namespace ta_vertex_parameter { struct polygon_type_0 { diff --git a/regs/gdrom_command_packet_format.csv b/regs/gdrom_command_packet_format.csv new file mode 100644 index 0000000..13dbd4c --- /dev/null +++ b/regs/gdrom_command_packet_format.csv @@ -0,0 +1,195 @@ +"test_unit",, +"0x00","command_code","0x00" +"0x01",, +"0x02",, +"0x03",, +"0x04",, +"0x05",, +"0x06",, +"0x07",, +"0x08",, +"0x09",, +"0x0a",, +"0x0b",, +,, +"req_stat",, +"0x00","command_code","0x10" +"0x01",, +"0x02","starting_address", +"0x03",, +"0x04","allocation_length", +"0x05",, +"0x06",, +"0x07",, +"0x08",, +"0x09",, +"0x0a",, +"0x0b",, +,, +"req_mode",, +"0x00","command_code","0x11" +"0x01",, +"0x02","starting_address", +"0x03",, +"0x04","allocation_length", +"0x05",, +"0x06",, +"0x07",, +"0x08",, +"0x09",, +"0x0a",, +"0x0b",, +,, +"set_mode",, +"0x00","command_code","0x12" +"0x01",, +"0x02","starting_address", +"0x03",, +"0x04","allocation_length", +"0x05",, +"0x06",, +"0x07",, +"0x08",, +"0x09",, +"0x0a",, +"0x0b",, +,, +"req_error",, +"0x00","command_code","0x13" +"0x01",, +"0x02",, +"0x03",, +"0x04","allocation_length", +"0x05",, +"0x06",, +"0x07",, +"0x08",, +"0x09",, +"0x0a",, +"0x0b",, +,, +"get_toc",, +"0x00","command_code","0x14" +"0x01","select", +"0x02",, +"0x03","allocation_length", +"0x04","allocation_length", +"0x05",, +"0x06",, +"0x07",, +"0x08",, +"0x09",, +"0x0a",, +"0x0b",, +,, +"req_ses",, +"0x00","command_code","0x15" +"0x01",, +"0x02","session_number", +"0x03",, +"0x04","allocation_length", +"0x05",, +"0x06",, +"0x07",, +"0x08",, +"0x09",, +"0x0a",, +"0x0b",, +,, +"cd_open",, +"0x00","command_code","0x16" +"0x01",, +"0x02",, +"0x03",, +"0x04",, +"0x05",, +"0x06",, +"0x07",, +"0x08",, +"0x09",, +"0x0a",, +"0x0b",, +,, +"cd_play",, +"0x00","command_code","0x20" +"0x01","parameter_type", +"0x02","starting_point", +"0x03","starting_point", +"0x04","starting_point", +"0x05",, +"0x06","repeat_times", +"0x07",, +"0x08","end_point", +"0x09","end_point", +"0x0a","end_point", +"0x0b",, +,, +"cd_seek",, +"0x00","command_code","0x21" +"0x01","parameter_type", +"0x02","seek_point", +"0x03","seek_point", +"0x04","seek_point", +"0x05",, +"0x06",, +"0x07",, +"0x08",, +"0x09",, +"0x0a",, +"0x0b",, +,, +"cd_scan",, +"0x00","command_code","0x22" +"0x01",, +"0x02","direction", +"0x03","speed", +"0x04",, +"0x05",, +"0x06",, +"0x07",, +"0x08",, +"0x09",, +"0x0a",, +"0x0b",, +,, +"cd_read",, +"0x00","command_code","0x30" +"0x01","data", +"0x02","starting_address", +"0x03","starting_address", +"0x04","starting_address", +"0x05",, +"0x06",, +"0x07",, +"0x08","transfer_length", +"0x09","transfer_length", +"0x0a","transfer_length", +"0x0b",, +,, +"cd_read2",, +"0x00","command_code","0x31" +"0x01","data", +"0x02","starting_address", +"0x03","starting_address", +"0x04","starting_address", +"0x05",, +"0x06","transfer_length", +"0x07","transfer_length", +"0x08","next_address", +"0x09","next_address", +"0x0a","next_address", +"0x0b",, +,, +"cd_scd",, +"0x00","command_code","0x40" +"0x01","data_format", +"0x02",, +"0x03","allocation_length", +"0x04","allocation_length", +"0x05",, +"0x06",, +"0x07",, +"0x08",, +"0x09",, +"0x0a",, +"0x0b",, diff --git a/regs/gdrom_command_packet_format.ods b/regs/gdrom_command_packet_format.ods new file mode 100644 index 0000000..c1587f6 Binary files /dev/null and b/regs/gdrom_command_packet_format.ods differ diff --git a/regs/gen/gdrom_command_packet_format.py b/regs/gen/gdrom_command_packet_format.py new file mode 100644 index 0000000..f473950 --- /dev/null +++ b/regs/gen/gdrom_command_packet_format.py @@ -0,0 +1,22 @@ +import sys + +from generate import renderer +from csv_input import read_input_headerless +from generic_sparse_struct import parse +from generic_sparse_struct import headers +from generic_sparse_struct import render_declarations + +def get_type(field_name: str): + return "uint8_t" + +if __name__ == "__main__": + rows = read_input_headerless(sys.argv[1]) + namespace = sys.argv[2] + declarations = parse(rows, + expected_offset=1, + expected_sizes={12}) + from pprint import pprint + render, out = renderer() + render(headers()) + render(render_declarations(namespace, declarations, get_type)) + print(out.getvalue()) diff --git a/regs/gen/generic_sparse_struct.py b/regs/gen/generic_sparse_struct.py new file mode 100644 index 0000000..9375724 --- /dev/null +++ b/regs/gen/generic_sparse_struct.py @@ -0,0 +1,159 @@ +from dataclasses import dataclass + +class EndOfInput(Exception): + pass + +def next_row(ix, rows, advance): + if ix >= len(rows): + raise EndOfInput + + if advance: + while rows[ix][0] == "": + ix += 1 + if ix >= len(rows): + raise EndOfInput + row = rows[ix] + ix += 1 + return ix, row + +@dataclass +class FieldDeclaration: + offset: int + name: str + default: int + array_length: str + +@dataclass +class StructDeclaration: + name: str + fields: list[FieldDeclaration] + size: int + +def parse_type_declaration(ix, rows, expected_offset, expected_sizes): + ix, row = next_row(ix, rows, advance=True) + assert len(row) in {2, 3}, row + struct_name, *empty = row + assert all(e == "" for e in empty) + fields = [] + last_offset = 0 - expected_offset + res_ix = 0 + + def terminate(): + size = last_offset + expected_offset + assert size in expected_sizes, size + return ix, StructDeclaration( + struct_name, + fields, + size + ) + + seen_names = set() + + while True: + try: + ix, row = next_row(ix, rows, advance=False) + except EndOfInput: + return terminate() + if row[0] == "": + return terminate() + else: + default = None + if len(row) == 2: + _offset, name = row + elif len(row) == 3: + _offset, name, _default = row + if _default.strip() != "": + default = int(_default, 16) + else: + assert False, row + offset = int(_offset, 16) + assert offset == last_offset + expected_offset, (hex(offset), hex(last_offset)) + last_offset = offset + if name == "": + name = f"_res{res_ix}" + res_ix += 1 + + if fields and fields[-1].name == name: + assert offset == fields[-1].offset + (fields[-1].array_length * expected_offset) + fields[-1].array_length += 1 + else: + assert name not in seen_names, row + seen_names.add(name) + fields.append(FieldDeclaration(offset, name, default, 1)) + +def parse(rows, expected_offset, expected_sizes): + ix = 0 + declarations = [] + while True: + try: + ix, declaration = parse_type_declaration(ix, rows, expected_offset, expected_sizes) + except EndOfInput: + break + declarations.append(declaration) + + return declarations + +def render_initializer(declaration, get_type): + initializer = f"{declaration.name}(" + padding = " " * len(initializer) + def start(i): + if i == 0: + return initializer + else: + return padding + + constructor_fields = [f for f in declaration.fields + if (not f.name.startswith('_res') + and not f.array_length > 1 + and f.default is None + )] + for i, field in enumerate(constructor_fields): + s = start(i) + type = get_type(field.name) + comma = ',' if i + 1 < len(constructor_fields) else '' + yield s + f"const {type} {field.name}" + comma + + if constructor_fields: + yield padding + ')' + else: + yield initializer + ')' + + for i, field in enumerate(declaration.fields): + value = field.name if not field.name.startswith('_res') else '0' + value = hex(field.default) if field.default is not None else value + value = '' if field.array_length > 1 else value + s = ':' if i == 0 else ',' + yield " " + s + f" {field.name}({value})" + yield "{ }" + +def render_static_assertions(declaration): + yield f"static_assert((sizeof ({declaration.name})) == {declaration.size});" + for field in declaration.fields: + yield f"static_assert((offsetof (struct {declaration.name}, {field.name})) == 0x{field.offset:02x});" + +def render_declaration(declaration, get_type): + yield f"struct {declaration.name} {{" + for field in declaration.fields: + type = get_type(field.name) + if field.array_length == 1: + yield f"{type} {field.name};" + else: + yield f"{type} {field.name}[{field.array_length}];" + yield "" + yield from render_initializer(declaration, get_type) + yield "};" + yield from render_static_assertions(declaration) + +def render_declarations(namespace, declarations, get_type): + yield f"namespace {namespace} {{" + for declaration in declarations: + yield from render_declaration(declaration, get_type) + yield "" + yield "}" + +def headers(): + yield "#pragma once" + yield "" + yield "#include " + yield "#include " + yield "" diff --git a/regs/gen/ta_parameter_format.py b/regs/gen/ta_parameter_format.py index 5ea3ee5..134ffc6 100644 --- a/regs/gen/ta_parameter_format.py +++ b/regs/gen/ta_parameter_format.py @@ -1,9 +1,10 @@ -from dataclasses import dataclass -from pprint import pprint import sys -from csv_input import read_input_headerless from generate import renderer +from csv_input import read_input_headerless +from generic_sparse_struct import parse +from generic_sparse_struct import headers +from generic_sparse_struct import render_declarations _field_types = { "parameter_control_word": "uint32_t", @@ -55,138 +56,13 @@ def get_type(field_name: str): assert match != None, field_name return match -class EndOfInput(Exception): - pass - -def next_row(ix, rows, advance): - if ix >= len(rows): - raise EndOfInput - - if advance: - while rows[ix][0] == "": - ix += 1 - if ix >= len(rows): - raise EndOfInput - row = rows[ix] - ix += 1 - return ix, row - -@dataclass -class FieldDeclaration: - offset: int - name: str - -@dataclass -class StructDeclaration: - name: str - fields: list[FieldDeclaration] - size: int - -def parse_type_declaration(ix, rows): - ix, row = next_row(ix, rows, advance=True) - assert len(row) == 2, row - struct_name, empty = row - assert empty == "", row - fields = [] - last_offset = -4 - res_ix = 0 - - def terminate(): - size = last_offset + 4 - assert size == 32 or size == 64, size - return ix, StructDeclaration( - struct_name, - fields, - size - ) - - while True: - try: - ix, row = next_row(ix, rows, advance=False) - except EndOfInput: - return terminate() - if row[0] == "": - return terminate() - else: - assert len(row) == 2, row - _offset, name = row - offset = int(_offset, 16) - assert offset == last_offset + 4, (hex(offset), hex(last_offset)) - last_offset = offset - if name == "": - name = f"_res{res_ix}" - res_ix += 1 - fields.append(FieldDeclaration(offset, name)) - -def parse(rows): - ix = 0 - declarations = [] - while True: - try: - ix, declaration = parse_type_declaration(ix, rows) - except EndOfInput: - break - declarations.append(declaration) - - return declarations - -def render_initializer(declaration): - initializer = f"{declaration.name}(" - padding = " " * len(initializer) - def start(i): - if i == 0: - return initializer - else: - return padding - - nonres_fields = [f for f in declaration.fields if not f.name.startswith('_res')] - for i, field in enumerate(nonres_fields): - s = start(i) - type = get_type(field.name) - comma = ',' if i + 1 < len(nonres_fields) else '' - yield s + f"const {type} {field.name}" + comma - yield padding + ')' - - for i, field in enumerate(declaration.fields): - value = field.name if not field.name.startswith('_res') else '0' - s = ':' if i == 0 else ',' - yield " " + s + f" {field.name}({value})" - yield "{ }" - - -def render_static_assertions(declaration): - yield f"static_assert((sizeof ({declaration.name})) == {declaration.size});" - for field in declaration.fields: - yield f"static_assert((offsetof (struct {declaration.name}, {field.name})) == 0x{field.offset:02x});" - -def render_declaration(declaration): - yield f"struct {declaration.name} {{" - for field in declaration.fields: - type = get_type(field.name) - yield f"{type} {field.name};" - yield "" - yield from render_initializer(declaration) - yield "};" - yield from render_static_assertions(declaration) - -def render_declarations(namespace, declarations): - yield f"namespace {namespace} {{" - for declaration in declarations: - yield from render_declaration(declaration) - yield "" - yield "}" - -def headers(): - yield "#pragma once" - yield "" - yield "#include " - yield "" - if __name__ == "__main__": rows = read_input_headerless(sys.argv[1]) namespace = sys.argv[2] - declarations = parse(rows) + declarations = parse(rows, + expected_offset=4, + expected_sizes={32, 64}) render, out = renderer() render(headers()) - render(render_declarations(namespace, declarations)) + render(render_declarations(namespace, declarations, get_type)) print(out.getvalue())