diff --git a/common.mk b/common.mk index 2aaf69b..20f52e6 100644 --- a/common.mk +++ b/common.mk @@ -160,12 +160,18 @@ 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/gdrom.hpp: regs/gdrom.csv regs/gen/gdrom.py + python regs/gen/gdrom.py $< gdrom > $@ + gdrom/gdrom_bits.hpp: regs/gdrom_bits.csv regs/gen/core_bits.py python regs/gen/core_bits.py $< gdrom > $@ 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 > $@ +iso9660/%.hpp: iso9660/%.csv iso9660/byte_position.py + python iso9660/byte_position.py $< > $@ + clean: find -P \ -regextype posix-egrep \ diff --git a/example/example.mk b/example/example.mk index e77505e..847933c 100644 --- a/example/example.mk +++ b/example/example.mk @@ -357,3 +357,10 @@ GDROM_TEST_OBJ = \ example/gdrom_test.elf: LDSCRIPT = $(LIB)/alt.lds example/gdrom_test.elf: $(START_OBJ) $(GDROM_TEST_OBJ) + +GDROM_ISO9660_OBJ = \ + example/gdrom_iso9660.o \ + sh7091/serial.o + +example/gdrom_iso9660.elf: LDSCRIPT = $(LIB)/alt.lds +example/gdrom_iso9660.elf: $(START_OBJ) $(GDROM_ISO9660_OBJ) diff --git a/example/gdrom_iso9660.cpp b/example/gdrom_iso9660.cpp new file mode 100644 index 0000000..ec2264e --- /dev/null +++ b/example/gdrom_iso9660.cpp @@ -0,0 +1,213 @@ +#include + +#include "memorymap.hpp" +#include "systembus.hpp" +#include "sh7091/serial.hpp" +#include "gdrom/gdrom.hpp" +#include "gdrom/gdrom_bits.hpp" +#include "gdrom/command_packet_format.hpp" +#include "gdrom/toc.hpp" + +#include "iso9660/primary_volume_descriptor.hpp" +#include "iso9660/directory_record.hpp" + +void pio_data(const uint8_t * data) +{ + while ((gdrom::status::bsy(gdrom_if.status) | gdrom::status::drq(gdrom_if.status)) != 0); + + gdrom_if.features = gdrom::features::dma::disable; + gdrom_if.drive_select = gdrom::drive_select::drive_select + | gdrom::drive_select::lun(0); + + gdrom_if.command = gdrom::command::code::packet_command; + while (gdrom::status::drq(gdrom_if.status) == 0); + + const uint16_t * buf = reinterpret_cast(&data[0]); + for (int i = 0; i < 6; i++) { + gdrom_if.data = buf[i]; + } + + while (gdrom::status::bsy(gdrom_if.status) != 0); +} + +void read_data(uint16_t * buf, const uint32_t length) +{ + serial::string("read_data drq interrupt_reason: "); + serial::integer(gdrom::status::drq(gdrom_if.status), ' '); + serial::integer(gdrom_if.interrupt_reason); + for (uint32_t i = 0; i < (length / 2); i++) { + buf[i] = gdrom_if.data; + } +} + +uint32_t toc__get_data_track_fad() +{ + auto packet = gdrom_command_packet_format::get_toc(0, // single-density + 0x0198 // maximum toc length + ); + serial::string("get_toc\n"); + pio_data(packet._data()); + + serial::string("byte_count: "); + serial::integer(gdrom_if.byte_count()); + uint16_t buf[gdrom_if.byte_count() / 2]; + read_data(buf, gdrom_if.byte_count()); + + serial::string("status: "); + serial::integer(gdrom_if.status); + + auto toc = reinterpret_cast(buf); + for (int i = 0; i < 99; i++) { + if (toc->track[i].fad() == 0xffffff) + break; + serial::string("track "); + serial::integer(i); + serial::integer(toc->track[i].fad()); + } + + // assume track 1 is the correct track + return toc->track[1].fad(); +} + +uint32_t cd_read(uint16_t * buf, + const uint32_t starting_address, + const uint32_t transfer_length) +{ + const uint8_t data_select = 0b0010; // data + const uint8_t expected_data_type = 0b100; // XA mode 2 form 1 + const uint8_t parameter_type = 0b0; // FAD specified + const uint8_t data = (data_select << 4) | (expected_data_type << 1) | (parameter_type << 0); + + auto packet = gdrom_command_packet_format::cd_read(data, + starting_address, + transfer_length); + + auto arst = packet._data(); + serial::string("cd_read\n"); + serial::string("starting_address: "); + serial::integer(starting_address); + pio_data(packet._data()); + + uint32_t length = 0; + while ((gdrom::status::drq(gdrom_if.status)) != 0) { + const uint32_t byte_count = gdrom_if.byte_count(); + length += byte_count; + read_data(buf, byte_count); + } + serial::string("status: "); + serial::integer(gdrom_if.status); + + serial::string("read length: "); + serial::integer(length); + return length; +} + +void main() +{ + // gdrom unlock undocumented register + g1_if.GDUNLOCK = 0x1fffff; + + // Without this read from system_boot_rom, the read value of + // gdrom_if.status is always 0xff + for(uint32_t i = 0; i < 0x200000 / 4; i++) { + (void)system_boot_rom[i]; + } + + const uint32_t fad = toc__get_data_track_fad(); + serial::character('\n'); + + const uint32_t primary_volume_descriptor = fad + 16; + uint16_t buf[2048 / 2]; + const uint32_t length0 = cd_read(buf, + primary_volume_descriptor, + 1 // one sector; 2048 bytes + ); + serial::character('\n'); + + auto pvd = reinterpret_cast(&buf[0]); + auto root_dr = reinterpret_cast(&pvd->directory_record_for_root_directory[0]); + + serial::string("primary volume descriptor:\n"); + serial::string(" standard_identifier: "); + serial::string(pvd->standard_identifier, 5); + serial::character('\n'); + serial::string(" root directory record:\n"); + serial::string(" location of extent: "); + serial::integer(root_dr->location_of_extent.get()); + serial::string(" data length: "); + serial::integer(root_dr->data_length.get()); + + serial::character('\n'); + + /* + for (int i = 0; i < 2048; i++) { + serial::hexlify(buf8[i]); + serial::character(' '); + if ((i % 16) == 15) + serial::character('\n'); + } + */ + serial::character('\n'); + + const uint32_t root_directory_extent = root_dr->location_of_extent.get(); + const uint32_t length1 = cd_read(buf, + root_directory_extent + 150, // 150? + 1 // one sector; 2048 bytes + ); + serial::character('\n'); + + auto buf8 = reinterpret_cast(buf); + uint32_t offset = 0; + while (true) { + serial::string("directory entry offset: "); + serial::integer(offset); + + auto dr = reinterpret_cast(&buf8[offset]); + if (dr->length_of_directory_record == 0) + break; + + serial::string(" length_of_directory_record: "); + serial::integer(dr->length_of_directory_record); + serial::string(" length_of_file_identifier: "); + serial::integer(dr->length_of_file_identifier); + serial::string(" file_identifier: "); + serial::string(dr->file_identifier, dr->length_of_file_identifier); + serial::character('\n'); + + if (dr->file_flags == 0) { + serial::string(" location_of_extent: "); + serial::integer(dr->location_of_extent.get()); + serial::string(" data_length: "); + serial::integer(dr->data_length.get()); + + if (dr->file_identifier[0] != '1') { + const uint32_t extent = dr->location_of_extent.get(); + + uint16_t buf2[2048 / 2]; + const uint32_t length1 = cd_read(buf2, + extent + 150, // 150? + 1 // one sector; 2048 bytes + ); + + auto file = reinterpret_cast(&buf2[0]); + serial::string("---begin file content---\n"); + serial::string(file, dr->data_length.get()); + serial::string("---end file content---\n"); + } + } + + offset += dr->length_of_directory_record; + } + + serial::integer(offset); + + while (1); +} + +/* + for (int i = 0; i < 12; i++) { + serial::hexlify(arst[i]); + serial::character(' '); + } + serial::character('\n'); +*/ diff --git a/example/gdrom_test.cpp b/example/gdrom_test.cpp index c691d9a..26dc028 100644 --- a/example/gdrom_test.cpp +++ b/example/gdrom_test.cpp @@ -1,8 +1,9 @@ -#include "gdrom/gdrom.hpp" -#include "gdrom/gdrom_bits.hpp" +#include + #include "memorymap.hpp" #include "systembus.hpp" - +#include "gdrom/gdrom.hpp" +#include "gdrom/gdrom_bits.hpp" #include "sh7091/serial.hpp" void test_unit() @@ -172,7 +173,7 @@ void get_toc() 41 00 2f 7c (lead-out information) */ -void cd_read() +void cd_read2() { // CD-ROM XA mode 2 form 1 @@ -182,7 +183,7 @@ void cd_read() const uint8_t data[12] = { - 0x31, // CD_READ + 0x31, // CD_READ2 (data_select << 4) | (expected_data_type << 1) | (parameter_type << 0), 0x00, // starting address (msb) @@ -238,7 +239,7 @@ void main() req_mode(); get_toc(); - cd_read(); + cd_read2(); while (1); } diff --git a/gdrom/command_packet_format_byte_order.hpp b/gdrom/command_packet_format_byte_order.hpp index 54439ff..e57c83a 100644 --- a/gdrom/command_packet_format_byte_order.hpp +++ b/gdrom/command_packet_format_byte_order.hpp @@ -7,15 +7,15 @@ namespace gdrom_command_packet_format { template <> constexpr void byte_order<2>(uint8_t * buf, const uint32_t n) { - buf[0] = n >> 8; - buf[1] = n >> 0; + buf[0] = (n >> 8) & 0xff; + buf[1] = (n >> 0) & 0xff; } template <> constexpr void byte_order<3>(uint8_t * buf, const uint32_t n) { - buf[0] = n >> 16; - buf[1] = n >> 8; - buf[1] = n >> 0; + buf[0] = (n >> 16) & 0xff; + buf[1] = (n >> 8) & 0xff; + buf[2] = (n >> 0) & 0xff; } } diff --git a/gdrom/gdrom.hpp b/gdrom/gdrom.hpp index e2e2841..7d4292d 100644 --- a/gdrom/gdrom.hpp +++ b/gdrom/gdrom.hpp @@ -22,11 +22,11 @@ struct gdrom_if_reg { reg8 sector_count; }; const reg8 _pad4[3]; - reg8 sector_number; + const reg8 sector_number; const reg8 _pad5[3]; - reg8 byte_control_low; + reg8 byte_count_low; const reg8 _pad6[3]; - reg8 byte_control_high; + reg8 byte_count_high; const reg8 _pad7[3]; reg8 drive_select; const reg8 _pad8[3]; @@ -34,6 +34,11 @@ struct gdrom_if_reg { const reg8 status; reg8 command; }; + + uint16_t byte_count() const + { + return (byte_count_high << 8) | (byte_count_low << 0); + } }; static_assert((offsetof (struct gdrom_if_reg, alternate_status)) == 24); @@ -44,8 +49,8 @@ static_assert((offsetof (struct gdrom_if_reg, features)) == 132); static_assert((offsetof (struct gdrom_if_reg, interrupt_reason)) == 136); static_assert((offsetof (struct gdrom_if_reg, sector_count)) == 136); static_assert((offsetof (struct gdrom_if_reg, sector_number)) == 140); -static_assert((offsetof (struct gdrom_if_reg, byte_control_low)) == 144); -static_assert((offsetof (struct gdrom_if_reg, byte_control_high)) == 148); +static_assert((offsetof (struct gdrom_if_reg, byte_count_low)) == 144); +static_assert((offsetof (struct gdrom_if_reg, byte_count_high)) == 148); static_assert((offsetof (struct gdrom_if_reg, drive_select)) == 152); static_assert((offsetof (struct gdrom_if_reg, status)) == 156); static_assert((offsetof (struct gdrom_if_reg, command)) == 156); diff --git a/gdrom/toc.hpp b/gdrom/toc.hpp new file mode 100644 index 0000000..03bd346 --- /dev/null +++ b/gdrom/toc.hpp @@ -0,0 +1,89 @@ +#include + +namespace gdrom_toc { + +struct track { + const uint8_t _control_adr; + const uint8_t _fad[3]; + + uint32_t fad() const + { + return (_fad[0] << 16) | (_fad[1] << 8) | (_fad[2] << 0); + } + + uint8_t control() const + { + return (_control_adr >> 4) & 0xf; + } + + uint8_t adr() const + { + return (_control_adr >> 0) & 0xf; + } +}; +static_assert((sizeof (track)) == 4); + +struct start_track { + const uint8_t _control_adr; + const uint8_t start_track_number; + const uint8_t _zero[2]; + + uint8_t control() const + { + return (_control_adr >> 4) & 0xf; + } + + uint8_t adr() const + { + return (_control_adr >> 0) & 0xf; + } +}; +static_assert((sizeof (start_track)) == 4); + +struct end_track { + const uint8_t _control_adr; + const uint8_t end_track_number; + const uint8_t _zero[2]; + + uint8_t control() const + { + return (_control_adr >> 4) & 0xf; + } + + uint8_t adr() const + { + return (_control_adr >> 0) & 0xf; + } +}; +static_assert((sizeof (end_track)) == 4); + +struct lead_out { + const uint8_t _control_adr; + const uint8_t _fad[3]; + + uint32_t fad() const + { + return (_fad[0] << 16) | (_fad[1] << 8) | (_fad[2] << 0); + } + + uint8_t control() const + { + return (_control_adr >> 4) & 0xf; + } + + uint8_t adr() const + { + return (_control_adr >> 0) & 0xf; + } +}; +static_assert((sizeof (lead_out)) == 4); + +struct toc { + struct track track[99]; + struct start_track start_track; + struct end_track end_track; + struct lead_out lead_out; +}; +static_assert((sizeof (toc)) == 408); + +} diff --git a/iso9660/byte_position.py b/iso9660/byte_position.py index 61fef12..8e7110b 100644 --- a/iso9660/byte_position.py +++ b/iso9660/byte_position.py @@ -1,6 +1,6 @@ import sys from dataclasses import dataclass -from os.path import splitext +from os import path from csv_input import read_input from generate import renderer @@ -89,6 +89,8 @@ def header(): yield "" def render_fields(input_name, fields): + yield "namespace iso9660 {" + yield f"struct {input_name} {{" for field in fields: field_size = (field.end - field.start) + 1 @@ -108,9 +110,12 @@ def render_fields(input_name, fields): for field in fields: yield f"static_assert((offsetof (struct {input_name}, {field.name})) == {field.start - 1});" + yield "}" # namespace + if __name__ == "__main__": input_file = sys.argv[1] - input_name, _ = splitext(input_file) + input_name0, _ = path.splitext(input_file) + _, input_name = path.split(input_name0) rows = read_input(input_file) fields = list(parse(rows)) render, out = renderer() diff --git a/iso9660/directory_record.hpp b/iso9660/directory_record.hpp index 63f2c7e..5b1d5c4 100644 --- a/iso9660/directory_record.hpp +++ b/iso9660/directory_record.hpp @@ -5,28 +5,29 @@ #include "uint_le_be.hpp" -struct directory_record { - const uint8_t length_of_directory_record; - const uint8_t extended_attribute_record_length; - const uint32_le_be location_of_extent; - const uint32_le_be data_length; - const uint8_t recording_date_and_time[7]; - const uint8_t file_flags; - const uint8_t file_unit_size; - const uint8_t interleave_gap_size; - const uint16_le_be volume_sequence_number; - const uint8_t length_of_file_identifier; - const uint8_t file_identifier[]; -}; - -static_assert((offsetof (struct directory_record, length_of_directory_ecord)) == 0); -static_assert((offsetof (struct directory_record, extended_attribute_record_length)) == 1); -static_assert((offsetof (struct directory_record, location_of_extent)) == 2); -static_assert((offsetof (struct directory_record, data_length)) == 10); -static_assert((offsetof (struct directory_record, recording_date_and_time)) == 18); -static_assert((offsetof (struct directory_record, file_flags)) == 25); -static_assert((offsetof (struct directory_record, file_unit_size)) == 26); -static_assert((offsetof (struct directory_record, interleave_gap_size)) == 27); -static_assert((offsetof (struct directory_record, volume_sequence_number)) == 28); -static_assert((offsetof (struct directory_record, length_of_file_identifier)) == 32); -static_assert((offsetof (struct directory_record, file_identifier)) == 33); +namespace iso9660 { + struct directory_record { + const uint8_t length_of_directory_record; + const uint8_t extended_attribute_record_length; + const uint32_le_be location_of_extent; + const uint32_le_be data_length; + const uint8_t recording_date_and_time[7]; + const uint8_t file_flags; + const uint8_t file_unit_size; + const uint8_t interleave_gap_size; + const uint16_le_be volume_sequence_number; + const uint8_t length_of_file_identifier; + const uint8_t file_identifier[]; + }; + static_assert((offsetof (struct directory_record, length_of_directory_record)) == 0); + static_assert((offsetof (struct directory_record, extended_attribute_record_length)) == 1); + static_assert((offsetof (struct directory_record, location_of_extent)) == 2); + static_assert((offsetof (struct directory_record, data_length)) == 10); + static_assert((offsetof (struct directory_record, recording_date_and_time)) == 18); + static_assert((offsetof (struct directory_record, file_flags)) == 25); + static_assert((offsetof (struct directory_record, file_unit_size)) == 26); + static_assert((offsetof (struct directory_record, interleave_gap_size)) == 27); + static_assert((offsetof (struct directory_record, volume_sequence_number)) == 28); + static_assert((offsetof (struct directory_record, length_of_file_identifier)) == 32); + static_assert((offsetof (struct directory_record, file_identifier)) == 33); +} diff --git a/iso9660/primary_volume_descriptor.hpp b/iso9660/primary_volume_descriptor.hpp index 6aa75d6..674d7e7 100644 --- a/iso9660/primary_volume_descriptor.hpp +++ b/iso9660/primary_volume_descriptor.hpp @@ -5,72 +5,73 @@ #include "uint_le_be.hpp" -struct primary_volume_descriptor { - const uint8_t volume_descriptor_type; - const uint8_t standard_identifier[5]; - const uint8_t volume_descriptor_version; - const uint8_t _res1; - const uint8_t system_identifier[32]; - const uint8_t volume_identifier[32]; - const uint8_t _res2[8]; - const uint32_le_be volume_space_size; - const uint8_t _res3[32]; - const uint16_le_be volume_set_size; - const uint16_le_be volume_sequence_number; - const uint16_le_be logical_block_size; - const uint32_le_be path_table_size; - const uint16_le_be location_of_occurrence_of_type_l_path_table; - const uint16_le_be location_of_optional_occurence_of_type_l_path_table; - const uint16_le_be location_of_occurence_of_type_m_path_table; - const uint16_le_be location_of_optional_occurence_of_type_m_path_table; - const uint8_t directory_record_for_root_directory[34]; - const uint8_t volume_set_identifier[128]; - const uint8_t publisher_identifier[128]; - const uint8_t data_preparer_identifier[128]; - const uint8_t application_identifier[128]; - const uint8_t copyright_file_identifier[37]; - const uint8_t abstract_file_identifier[37]; - const uint8_t bibliographic_file_identifier[37]; - const uint8_t volume_creation_date_and_time[17]; - const uint8_t volume_modification_date_and_time[17]; - const uint8_t volume_expiration_date_and_time[17]; - const uint8_t volume_effective_date_and_time[17]; - const uint8_t file_structure_version; - const uint8_t _res4; - const uint8_t application_use[512]; - const uint8_t _res5[653]; -}; - -static_assert((offsetof (struct primary_volume_descriptor, volume_descriptor_type)) == 0); -static_assert((offsetof (struct primary_volume_descriptor, standard_identifier)) == 1); -static_assert((offsetof (struct primary_volume_descriptor, volume_descriptor_version)) == 6); -static_assert((offsetof (struct primary_volume_descriptor, _res1)) == 7); -static_assert((offsetof (struct primary_volume_descriptor, system_identifier)) == 8); -static_assert((offsetof (struct primary_volume_descriptor, volume_identifier)) == 40); -static_assert((offsetof (struct primary_volume_descriptor, _res2)) == 72); -static_assert((offsetof (struct primary_volume_descriptor, volume_space_size)) == 80); -static_assert((offsetof (struct primary_volume_descriptor, _res3)) == 88); -static_assert((offsetof (struct primary_volume_descriptor, volume_set_size)) == 120); -static_assert((offsetof (struct primary_volume_descriptor, volume_sequence_number)) == 124); -static_assert((offsetof (struct primary_volume_descriptor, logical_block_size)) == 128); -static_assert((offsetof (struct primary_volume_descriptor, path_table_size)) == 132); -static_assert((offsetof (struct primary_volume_descriptor, location_of_occurrence_of_type_l_path_table)) == 140); -static_assert((offsetof (struct primary_volume_descriptor, location_of_optional_occurence_of_type_l_path_table)) == 144); -static_assert((offsetof (struct primary_volume_descriptor, location_of_occurence_of_type_m_path_table)) == 148); -static_assert((offsetof (struct primary_volume_descriptor, location_of_optional_occurence_of_type_m_path_table)) == 152); -static_assert((offsetof (struct primary_volume_descriptor, directory_record_for_root_directory)) == 156); -static_assert((offsetof (struct primary_volume_descriptor, volume_set_identifier)) == 190); -static_assert((offsetof (struct primary_volume_descriptor, publisher_identifier)) == 318); -static_assert((offsetof (struct primary_volume_descriptor, data_preparer_identifier)) == 446); -static_assert((offsetof (struct primary_volume_descriptor, application_identifier)) == 574); -static_assert((offsetof (struct primary_volume_descriptor, copyright_file_identifier)) == 702); -static_assert((offsetof (struct primary_volume_descriptor, abstract_file_identifier)) == 739); -static_assert((offsetof (struct primary_volume_descriptor, bibliographic_file_identifier)) == 776); -static_assert((offsetof (struct primary_volume_descriptor, volume_creation_date_and_time)) == 813); -static_assert((offsetof (struct primary_volume_descriptor, volume_modification_date_and_time)) == 830); -static_assert((offsetof (struct primary_volume_descriptor, volume_expiration_date_and_time)) == 847); -static_assert((offsetof (struct primary_volume_descriptor, volume_effective_date_and_time)) == 864); -static_assert((offsetof (struct primary_volume_descriptor, file_structure_version)) == 881); -static_assert((offsetof (struct primary_volume_descriptor, _res4)) == 882); -static_assert((offsetof (struct primary_volume_descriptor, application_use)) == 883); -static_assert((offsetof (struct primary_volume_descriptor, _res5)) == 1395); +namespace iso9660 { + struct primary_volume_descriptor { + const uint8_t volume_descriptor_type; + const uint8_t standard_identifier[5]; + const uint8_t volume_descriptor_version; + const uint8_t _res1; + const uint8_t system_identifier[32]; + const uint8_t volume_identifier[32]; + const uint8_t _res2[8]; + const uint32_le_be volume_space_size; + const uint8_t _res3[32]; + const uint16_le_be volume_set_size; + const uint16_le_be volume_sequence_number; + const uint16_le_be logical_block_size; + const uint32_le_be path_table_size; + const uint16_le_be location_of_occurrence_of_type_l_path_table; + const uint16_le_be location_of_optional_occurence_of_type_l_path_table; + const uint16_le_be location_of_occurence_of_type_m_path_table; + const uint16_le_be location_of_optional_occurence_of_type_m_path_table; + const uint8_t directory_record_for_root_directory[34]; + const uint8_t volume_set_identifier[128]; + const uint8_t publisher_identifier[128]; + const uint8_t data_preparer_identifier[128]; + const uint8_t application_identifier[128]; + const uint8_t copyright_file_identifier[37]; + const uint8_t abstract_file_identifier[37]; + const uint8_t bibliographic_file_identifier[37]; + const uint8_t volume_creation_date_and_time[17]; + const uint8_t volume_modification_date_and_time[17]; + const uint8_t volume_expiration_date_and_time[17]; + const uint8_t volume_effective_date_and_time[17]; + const uint8_t file_structure_version; + const uint8_t _res4; + const uint8_t application_use[512]; + const uint8_t _res5[653]; + }; + static_assert((offsetof (struct primary_volume_descriptor, volume_descriptor_type)) == 0); + static_assert((offsetof (struct primary_volume_descriptor, standard_identifier)) == 1); + static_assert((offsetof (struct primary_volume_descriptor, volume_descriptor_version)) == 6); + static_assert((offsetof (struct primary_volume_descriptor, _res1)) == 7); + static_assert((offsetof (struct primary_volume_descriptor, system_identifier)) == 8); + static_assert((offsetof (struct primary_volume_descriptor, volume_identifier)) == 40); + static_assert((offsetof (struct primary_volume_descriptor, _res2)) == 72); + static_assert((offsetof (struct primary_volume_descriptor, volume_space_size)) == 80); + static_assert((offsetof (struct primary_volume_descriptor, _res3)) == 88); + static_assert((offsetof (struct primary_volume_descriptor, volume_set_size)) == 120); + static_assert((offsetof (struct primary_volume_descriptor, volume_sequence_number)) == 124); + static_assert((offsetof (struct primary_volume_descriptor, logical_block_size)) == 128); + static_assert((offsetof (struct primary_volume_descriptor, path_table_size)) == 132); + static_assert((offsetof (struct primary_volume_descriptor, location_of_occurrence_of_type_l_path_table)) == 140); + static_assert((offsetof (struct primary_volume_descriptor, location_of_optional_occurence_of_type_l_path_table)) == 144); + static_assert((offsetof (struct primary_volume_descriptor, location_of_occurence_of_type_m_path_table)) == 148); + static_assert((offsetof (struct primary_volume_descriptor, location_of_optional_occurence_of_type_m_path_table)) == 152); + static_assert((offsetof (struct primary_volume_descriptor, directory_record_for_root_directory)) == 156); + static_assert((offsetof (struct primary_volume_descriptor, volume_set_identifier)) == 190); + static_assert((offsetof (struct primary_volume_descriptor, publisher_identifier)) == 318); + static_assert((offsetof (struct primary_volume_descriptor, data_preparer_identifier)) == 446); + static_assert((offsetof (struct primary_volume_descriptor, application_identifier)) == 574); + static_assert((offsetof (struct primary_volume_descriptor, copyright_file_identifier)) == 702); + static_assert((offsetof (struct primary_volume_descriptor, abstract_file_identifier)) == 739); + static_assert((offsetof (struct primary_volume_descriptor, bibliographic_file_identifier)) == 776); + static_assert((offsetof (struct primary_volume_descriptor, volume_creation_date_and_time)) == 813); + static_assert((offsetof (struct primary_volume_descriptor, volume_modification_date_and_time)) == 830); + static_assert((offsetof (struct primary_volume_descriptor, volume_expiration_date_and_time)) == 847); + static_assert((offsetof (struct primary_volume_descriptor, volume_effective_date_and_time)) == 864); + static_assert((offsetof (struct primary_volume_descriptor, file_structure_version)) == 881); + static_assert((offsetof (struct primary_volume_descriptor, _res4)) == 882); + static_assert((offsetof (struct primary_volume_descriptor, application_use)) == 883); + static_assert((offsetof (struct primary_volume_descriptor, _res5)) == 1395); +} diff --git a/iso9660/uint_le_be.hpp b/iso9660/uint_le_be.hpp index 1e6ded3..5fcf80d 100644 --- a/iso9660/uint_le_be.hpp +++ b/iso9660/uint_le_be.hpp @@ -2,7 +2,6 @@ #include #include -#include template struct uint_le_be { diff --git a/regs/gdrom.csv b/regs/gdrom.csv index cc834f3..636fa7e 100644 --- a/regs/gdrom.csv +++ b/regs/gdrom.csv @@ -6,9 +6,9 @@ "0084","1","features","W", "0088","1","interrupt_reason","R", "0088","1","sector_count","W", -"008C","1","sector_number","RW", -"0090","1","byte_control_low","RW", -"0094","1","byte_control_high","RW", +"008C","1","sector_number","R", +"0090","1","byte_count_low","RW", +"0094","1","byte_count_high","RW", "0098","1","drive_select","RW", "009C","1","status","R", "009C","1","command","W", diff --git a/regs/gdrom.ods b/regs/gdrom.ods index 434c1e1..f6f6647 100644 Binary files a/regs/gdrom.ods and b/regs/gdrom.ods differ diff --git a/regs/gen/gdrom.py b/regs/gen/gdrom.py index b9cbca0..4d80478 100644 --- a/regs/gen/gdrom.py +++ b/regs/gen/gdrom.py @@ -40,6 +40,12 @@ def group_by_address(rows): return list(sorted(_groups.items(), key=lambda kv: kv[0])) +def byte_count(): + yield "uint16_t byte_count() const" + yield "{" + yield "return (byte_count_high << 8) | (byte_count_low << 0);" + yield "}" + def render_groups(groups): next_address = 0 reserved_num = 0 @@ -67,6 +73,9 @@ def render_groups(groups): next_address = address + group[0].size + yield "" + yield from byte_count() + yield "};" diff --git a/sh7091/serial.cpp b/sh7091/serial.cpp index 2d4c611..b2d8032 100644 --- a/sh7091/serial.cpp +++ b/sh7091/serial.cpp @@ -47,6 +47,14 @@ void string(const char * s) } } +void string(const uint8_t * s, uint32_t len) +{ + while (len > 0) { + character(*s++); + len--; + } +} + void hexlify(const uint8_t n) { constexpr uint32_t length = 2; diff --git a/sh7091/serial.hpp b/sh7091/serial.hpp index 27a9ad8..9450830 100644 --- a/sh7091/serial.hpp +++ b/sh7091/serial.hpp @@ -6,6 +6,8 @@ void character(const char c); void string(const char * s); +void string(const uint8_t * s, uint32_t len); + void hexlify(const uint8_t n); template