From 967caa1b2262c57f539127ffc7e69f82a457f48a Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Wed, 1 Jan 2025 04:51:41 -0600 Subject: [PATCH] add Gdrom/GdromBits/GdromCommandPacketFormat --- generate.sh | 17 +- regs/gdrom_command_packet_format.py | 20 + regs/sparse_struct.py | 2 +- regs/sparse_struct_java.py | 42 +- sega/dreamcast/gdrom/Gdrom.java | 17 + sega/dreamcast/gdrom/GdromBits.java | 104 ++++ .../gdrom/GdromCommandPacketFormat.java | 554 ++++++++++++++++++ 7 files changed, 741 insertions(+), 15 deletions(-) create mode 100644 regs/gdrom_command_packet_format.py create mode 100644 sega/dreamcast/gdrom/Gdrom.java create mode 100644 sega/dreamcast/gdrom/GdromBits.java create mode 100644 sega/dreamcast/gdrom/GdromCommandPacketFormat.java diff --git a/generate.sh b/generate.sh index 9b030aa..b5b6eee 100644 --- a/generate.sh +++ b/generate.sh @@ -1,12 +1,14 @@ python gen_decoder.py > c/decode.inc.c -python regs/register_gen.py ../dreamcast/regs/holly.csv holly 0xa05f8000 > sega/dreamcast/holly/Holly.java -python regs/register_gen.py ../dreamcast/regs/systembus.csv systembus 0xa05f6800 > sega/dreamcast/systembus/Systembus.java +python regs/register_gen.py ../dreamcast/regs/holly.csv holly 0xa05f8000 > sega/dreamcast/holly/Holly.java +python regs/register_gen.py ../dreamcast/regs/systembus.csv systembus 0xa05f6800 > sega/dreamcast/systembus/Systembus.java +python regs/register_gen.py ~/dreamcast/regs/gdrom.csv gdrom 0xa05f7000 > sega/dreamcast/gdrom/Gdrom.java -python regs/bits_gen.py ../dreamcast/regs/core_bits.csv holly CoreBits > sega/dreamcast/holly/CoreBits.java -python regs/bits_gen.py ../dreamcast/regs/ta_bits.csv holly TABits > sega/dreamcast/holly/TABits.java -python regs/bits_gen.py ../dreamcast/regs/isp_tsp.csv holly ISPTSP > sega/dreamcast/holly/ISPTSP.java -python regs/bits_gen.py ../dreamcast/regs/ta_parameter.csv holly TAParameter > sega/dreamcast/holly/TAParameter.java +python regs/bits_gen.py ../dreamcast/regs/core_bits.csv holly CoreBits > sega/dreamcast/holly/CoreBits.java +python regs/bits_gen.py ../dreamcast/regs/ta_bits.csv holly TABits > sega/dreamcast/holly/TABits.java +python regs/bits_gen.py ../dreamcast/regs/isp_tsp.csv holly ISPTSP > sega/dreamcast/holly/ISPTSP.java +python regs/bits_gen.py ../dreamcast/regs/ta_parameter.csv holly TAParameter > sega/dreamcast/holly/TAParameter.java +python regs/bits_gen.py ..//dreamcast/regs/gdrom_bits.csv gdrom GdromBits > sega/dreamcast/gdrom/GdromBits.java python regs/bits_gen.py ../dreamcast/regs/systembus_bits.csv systembus SystembusBits > sega/dreamcast/systembus/SystembusBits.java @@ -15,7 +17,8 @@ python regs/ta_parameters.py ../dreamcast/regs/global_parameter_format.csv holly PYTHONPATH=./regs/ python ../model_generator/generate_java.py ../untitled.obj UntitledModel > ./model/UntitledModel.java - python images/color_convert.py images/java_cup.png argb4444 images/java_cup.data python images/color_convert.py images/java_text.png argb4444 images/java_text.data python images/color_convert.py images/java_powered.png argb4444 images/java_powered.data + +python regs/gdrom_command_packet_format.py ../dreamcast/regs/gdrom_command_packet_format.csv gdrom GdromCommandPacketFormat > sega/dreamcast/gdrom/GdromCommandPacketFormat.java diff --git a/regs/gdrom_command_packet_format.py b/regs/gdrom_command_packet_format.py new file mode 100644 index 0000000..b71146a --- /dev/null +++ b/regs/gdrom_command_packet_format.py @@ -0,0 +1,20 @@ +import sys + +from generate import renderer +from csv_input import read_input_headerless +from sparse_struct import parse +from sparse_struct_java import render_declarations + +def get_type(field_name: str): + return "byte" + +if __name__ == "__main__": + rows = read_input_headerless(sys.argv[1]) + package_name = sys.argv[2] + class_name = sys.argv[3] + declarations = parse(rows, + expected_offset=1, + expected_sizes={12}) + render, out = renderer(indent_length=4) + render(render_declarations(get_type, package_name, class_name, declarations, want_get_byte=True)) + sys.stdout.write(out.getvalue()) diff --git a/regs/sparse_struct.py b/regs/sparse_struct.py index 0f7b97e..dff85aa 100644 --- a/regs/sparse_struct.py +++ b/regs/sparse_struct.py @@ -67,7 +67,7 @@ def parse_type_declaration(ix, rows, expected_offset, expected_sizes): else: assert False, row offset = int(_offset, 16) - assert offset == last_offset + expected_offset, (hex(offset), hex(last_offset)) + assert offset == last_offset + expected_offset, (hex(offset), hex(last_offset), expected_offset) last_offset = offset if name == "": name = f"_res{res_ix}" diff --git a/regs/sparse_struct_java.py b/regs/sparse_struct_java.py index a8c1219..7b074e1 100644 --- a/regs/sparse_struct_java.py +++ b/regs/sparse_struct_java.py @@ -1,8 +1,11 @@ def render_fields(get_type, fields): for field in fields: field_type = get_type(field.name) - assert field.array_length == 1 - yield f"public {field_type} {field.name};" + if field.array_length == 1: + yield f"public {field_type} {field.name};" + else: + for i in range(field.array_length): + yield f"public {field_type} {field.name}{i};" def render_constructor(get_type, declaration): initializer = f"public {declaration.name}(" @@ -19,7 +22,7 @@ def render_constructor(get_type, declaration): for i, field in enumerate(constructor_fields): s = start(i) assert field.array_length <= 4, field - type = get_type(field.name) if field.array_length == 1 else "uint32_t" + type = get_type(field.name) if field.array_length == 1 else "int" comma = ',' if i + 1 < len(constructor_fields) else '' yield s + f"{type} {field.name}" + comma @@ -32,23 +35,48 @@ def render_constructor(get_type, declaration): value = field.name if not field.name.startswith('_res') else '0' value = hex(field.default) if field.default is not None else value s = ':' if i == 0 else ',' - yield f"this.{field.name} = {value};" + if field.array_length == 1: + yield f"this.{field.name} = {value};" + else: + max_shift = 8 * (field.array_length - 1) + for i in range(field.array_length): + shift = max_shift - (i * 8) + yield f"this.{field.name}{i} = ({field.name} >> {shift}) & 0xff;" yield "}" array_fields = [f for f in declaration.fields if f.array_length > 1] -def render_declaration(get_type, declaration): +def render_get_byte(fields): + ix = 0 + yield "public get_byte(int ix) {" + yield "switch (ix) {" + for field in fields: + if "_res" in field.name: + pass + elif field.array_length == 1: + yield f"case {ix}: return {field.name};" + else: + for i in range(field.array_length): + yield f"case {ix + i}: return {field.name}{i};" + ix += field.array_length + yield "default: return 0;" + yield "}" + yield "}" + +def render_declaration(get_type, declaration, want_get_byte): yield f"public static class {declaration.name} {{" yield from render_fields(get_type, declaration.fields) yield from render_constructor(get_type, declaration) + if want_get_byte: + yield from render_get_byte(declaration.fields) yield "}" -def render_declarations(get_type, package_name, class_name, declarations): +def render_declarations(get_type, package_name, class_name, declarations, want_get_byte=False): yield f"package sega.dreamcast.{package_name};" yield "" yield f"public class {class_name} {{" for declaration in declarations: - yield from render_declaration(get_type, declaration) + yield from render_declaration(get_type, declaration, want_get_byte) yield "}" diff --git a/sega/dreamcast/gdrom/Gdrom.java b/sega/dreamcast/gdrom/Gdrom.java new file mode 100644 index 0000000..d4ce372 --- /dev/null +++ b/sega/dreamcast/gdrom/Gdrom.java @@ -0,0 +1,17 @@ +package sega.dreamcast.gdrom; + +public class Gdrom { + public static final int alternate_status = 0xa05f7018; + public static final int device_control = 0xa05f7018; + public static final int data = 0xa05f7080; + public static final int error = 0xa05f7084; + public static final int features = 0xa05f7084; + public static final int interrupt_reason = 0xa05f7088; + public static final int sector_count = 0xa05f7088; + public static final int sector_number = 0xa05f708c; + public static final int byte_count_low = 0xa05f7090; + public static final int byte_count_high = 0xa05f7094; + public static final int drive_select = 0xa05f7098; + public static final int status = 0xa05f709c; + public static final int command = 0xa05f709c; +} diff --git a/sega/dreamcast/gdrom/GdromBits.java b/sega/dreamcast/gdrom/GdromBits.java new file mode 100644 index 0000000..47551f5 --- /dev/null +++ b/sega/dreamcast/gdrom/GdromBits.java @@ -0,0 +1,104 @@ +package sega.dreamcast.gdrom; + +public class GdromBits { + public static int status__bsy(int n) { + return (n >> 7) & 1; + } + public static int status__drdy(int n) { + return (n >> 6) & 1; + } + public static int status__df(int n) { + return (n >> 5) & 1; + } + public static int status__dsc(int n) { + return (n >> 4) & 1; + } + public static int status__drq(int n) { + return (n >> 3) & 1; + } + public static int status__corr(int n) { + return (n >> 2) & 1; + } + public static int status__check(int n) { + return (n >> 0) & 1; + } + public static int alternate_status__bsy(int n) { + return (n >> 7) & 1; + } + public static int alternate_status__drdy(int n) { + return (n >> 6) & 1; + } + public static int alternate_status__df(int n) { + return (n >> 5) & 1; + } + public static int alternate_status__dsc(int n) { + return (n >> 4) & 1; + } + public static int alternate_status__drq(int n) { + return (n >> 3) & 1; + } + public static int alternate_status__corr(int n) { + return (n >> 2) & 1; + } + public static int alternate_status__check(int n) { + return (n >> 0) & 1; + } + public static final int command__code__soft_reset = 8 << 0; + public static final int command__code__execute_device_diagnostic = 144 << 0; + public static final int command__code__nop = 0 << 0; + public static final int command__code__packet_command = 160 << 0; + public static final int command__code__identify_device = 161 << 0; + public static final int command__code__set_features = 239 << 0; + public static final int device_control__device_control = 8 << 0; + public static final int device_control__srst = 1 << 2; + public static final int device_control__nien = 1 << 1; + public static final int drive_select__drive_select = 10 << 4; + public static int drive_select__lun(int n) { + return (n & 15) << 0; + } + public static int error__sense_key(int n) { + return (n >> 4) & 15; + } + public static int error__mcr(int n) { + return (n >> 3) & 1; + } + public static int error__abrt(int n) { + return (n >> 2) & 1; + } + public static int error__eomf(int n) { + return (n >> 1) & 1; + } + public static int error__ili(int n) { + return (n >> 0) & 1; + } + public static final int features__dma__disable = 0 << 0; + public static final int features__dma__enable = 1 << 0; + public static final int features_ata__set_clear__clear = 0 << 7; + public static final int features_ata__set_clear__set = 1 << 7; + public static final int features_ata__command__set_transfer_mode = 3 << 0; + public static int interrupt_reason__io(int n) { + return (n >> 1) & 1; + } + public static int interrupt_reason__cod(int n) { + return (n >> 0) & 1; + } + public static final int sector_count__transfer_mode__pio_default_transfer_mode = 0 << 0; + public static final int sector_count__transfer_mode__pio_flow_control_transfer_mode = 8 << 0; + public static final int sector_count__transfer_mode__single_word_dma_mode = 16 << 0; + public static final int sector_count__transfer_mode__multi_word_dma_mode = 32 << 0; + public static int sector_number__disc_format(int n) { + return (n >> 4) & 15; + } + public static int sector_number__status(int n) { + return (n >> 0) & 15; + } + public static final int error_ata__sense_key__no_sense = 0 << 0; + public static final int error_ata__sense_key__recovered_error = 1 << 0; + public static final int error_ata__sense_key__not_ready = 2 << 0; + public static final int error_ata__sense_key__medium_error = 3 << 0; + public static final int error_ata__sense_key__hardware_error = 4 << 0; + public static final int error_ata__sense_key__illegal_request = 5 << 0; + public static final int error_ata__sense_key__unit_attention = 6 << 0; + public static final int error_ata__sense_key__data_protect = 7 << 0; + public static final int error_ata__sense_key__aborted_command = 11 << 0; +} diff --git a/sega/dreamcast/gdrom/GdromCommandPacketFormat.java b/sega/dreamcast/gdrom/GdromCommandPacketFormat.java new file mode 100644 index 0000000..b14be00 --- /dev/null +++ b/sega/dreamcast/gdrom/GdromCommandPacketFormat.java @@ -0,0 +1,554 @@ +package sega.dreamcast.gdrom; + + +public class GdromCommandPacketFormat { + public static class test_unit { + public byte command_code; + public byte _res0; + public byte _res1; + public byte _res2; + public byte _res3; + public byte _res4; + public byte _res5; + public byte _res6; + public byte _res7; + public byte _res8; + public byte _res9; + public byte _res10; + public test_unit() { + this.command_code = 0x0; + this._res0 = 0; + this._res1 = 0; + this._res2 = 0; + this._res3 = 0; + this._res4 = 0; + this._res5 = 0; + this._res6 = 0; + this._res7 = 0; + this._res8 = 0; + this._res9 = 0; + this._res10 = 0; + } + public get_byte(int ix) { + switch (ix) { + case 0: return command_code; + default: return 0; + } + } + } + public static class req_stat { + public byte command_code; + public byte _res0; + public byte starting_address; + public byte _res1; + public byte allocation_length; + public byte _res2; + public byte _res3; + public byte _res4; + public byte _res5; + public byte _res6; + public byte _res7; + public byte _res8; + public req_stat(byte starting_address, + byte allocation_length + ) { + this.command_code = 0x10; + this._res0 = 0; + this.starting_address = starting_address; + this._res1 = 0; + this.allocation_length = allocation_length; + this._res2 = 0; + this._res3 = 0; + this._res4 = 0; + this._res5 = 0; + this._res6 = 0; + this._res7 = 0; + this._res8 = 0; + } + public get_byte(int ix) { + switch (ix) { + case 0: return command_code; + case 2: return starting_address; + case 4: return allocation_length; + default: return 0; + } + } + } + public static class req_mode { + public byte command_code; + public byte _res0; + public byte starting_address; + public byte _res1; + public byte allocation_length; + public byte _res2; + public byte _res3; + public byte _res4; + public byte _res5; + public byte _res6; + public byte _res7; + public byte _res8; + public req_mode(byte starting_address, + byte allocation_length + ) { + this.command_code = 0x11; + this._res0 = 0; + this.starting_address = starting_address; + this._res1 = 0; + this.allocation_length = allocation_length; + this._res2 = 0; + this._res3 = 0; + this._res4 = 0; + this._res5 = 0; + this._res6 = 0; + this._res7 = 0; + this._res8 = 0; + } + public get_byte(int ix) { + switch (ix) { + case 0: return command_code; + case 2: return starting_address; + case 4: return allocation_length; + default: return 0; + } + } + } + public static class set_mode { + public byte command_code; + public byte _res0; + public byte starting_address; + public byte _res1; + public byte allocation_length; + public byte _res2; + public byte _res3; + public byte _res4; + public byte _res5; + public byte _res6; + public byte _res7; + public byte _res8; + public set_mode(byte starting_address, + byte allocation_length + ) { + this.command_code = 0x12; + this._res0 = 0; + this.starting_address = starting_address; + this._res1 = 0; + this.allocation_length = allocation_length; + this._res2 = 0; + this._res3 = 0; + this._res4 = 0; + this._res5 = 0; + this._res6 = 0; + this._res7 = 0; + this._res8 = 0; + } + public get_byte(int ix) { + switch (ix) { + case 0: return command_code; + case 2: return starting_address; + case 4: return allocation_length; + default: return 0; + } + } + } + public static class req_error { + public byte command_code; + public byte _res0; + public byte _res1; + public byte _res2; + public byte allocation_length; + public byte _res3; + public byte _res4; + public byte _res5; + public byte _res6; + public byte _res7; + public byte _res8; + public byte _res9; + public req_error(byte allocation_length + ) { + this.command_code = 0x13; + this._res0 = 0; + this._res1 = 0; + this._res2 = 0; + this.allocation_length = allocation_length; + this._res3 = 0; + this._res4 = 0; + this._res5 = 0; + this._res6 = 0; + this._res7 = 0; + this._res8 = 0; + this._res9 = 0; + } + public get_byte(int ix) { + switch (ix) { + case 0: return command_code; + case 4: return allocation_length; + default: return 0; + } + } + } + public static class get_toc { + public byte command_code; + public byte select; + public byte _res0; + public byte allocation_length0; + public byte allocation_length1; + public byte _res1; + public byte _res2; + public byte _res3; + public byte _res4; + public byte _res5; + public byte _res6; + public byte _res7; + public get_toc(byte select, + int allocation_length + ) { + this.command_code = 0x14; + this.select = select; + this._res0 = 0; + this.allocation_length0 = (allocation_length >> 8) & 0xff; + this.allocation_length1 = (allocation_length >> 0) & 0xff; + this._res1 = 0; + this._res2 = 0; + this._res3 = 0; + this._res4 = 0; + this._res5 = 0; + this._res6 = 0; + this._res7 = 0; + } + public get_byte(int ix) { + switch (ix) { + case 0: return command_code; + case 1: return select; + case 3: return allocation_length0; + case 4: return allocation_length1; + default: return 0; + } + } + } + public static class req_ses { + public byte command_code; + public byte _res0; + public byte session_number; + public byte _res1; + public byte allocation_length; + public byte _res2; + public byte _res3; + public byte _res4; + public byte _res5; + public byte _res6; + public byte _res7; + public byte _res8; + public req_ses(byte session_number, + byte allocation_length + ) { + this.command_code = 0x15; + this._res0 = 0; + this.session_number = session_number; + this._res1 = 0; + this.allocation_length = allocation_length; + this._res2 = 0; + this._res3 = 0; + this._res4 = 0; + this._res5 = 0; + this._res6 = 0; + this._res7 = 0; + this._res8 = 0; + } + public get_byte(int ix) { + switch (ix) { + case 0: return command_code; + case 2: return session_number; + case 4: return allocation_length; + default: return 0; + } + } + } + public static class cd_open { + public byte command_code; + public byte _res0; + public byte _res1; + public byte _res2; + public byte _res3; + public byte _res4; + public byte _res5; + public byte _res6; + public byte _res7; + public byte _res8; + public byte _res9; + public byte _res10; + public cd_open() { + this.command_code = 0x16; + this._res0 = 0; + this._res1 = 0; + this._res2 = 0; + this._res3 = 0; + this._res4 = 0; + this._res5 = 0; + this._res6 = 0; + this._res7 = 0; + this._res8 = 0; + this._res9 = 0; + this._res10 = 0; + } + public get_byte(int ix) { + switch (ix) { + case 0: return command_code; + default: return 0; + } + } + } + public static class cd_play { + public byte command_code; + public byte parameter_type; + public byte starting_point0; + public byte starting_point1; + public byte starting_point2; + public byte _res0; + public byte repeat_times; + public byte _res1; + public byte end_point0; + public byte end_point1; + public byte end_point2; + public byte _res2; + public cd_play(byte parameter_type, + int starting_point, + byte repeat_times, + int end_point + ) { + this.command_code = 0x20; + this.parameter_type = parameter_type; + this.starting_point0 = (starting_point >> 16) & 0xff; + this.starting_point1 = (starting_point >> 8) & 0xff; + this.starting_point2 = (starting_point >> 0) & 0xff; + this._res0 = 0; + this.repeat_times = repeat_times; + this._res1 = 0; + this.end_point0 = (end_point >> 16) & 0xff; + this.end_point1 = (end_point >> 8) & 0xff; + this.end_point2 = (end_point >> 0) & 0xff; + this._res2 = 0; + } + public get_byte(int ix) { + switch (ix) { + case 0: return command_code; + case 1: return parameter_type; + case 2: return starting_point0; + case 3: return starting_point1; + case 4: return starting_point2; + case 6: return repeat_times; + case 8: return end_point0; + case 9: return end_point1; + case 10: return end_point2; + default: return 0; + } + } + } + public static class cd_seek { + public byte command_code; + public byte parameter_type; + public byte seek_point0; + public byte seek_point1; + public byte seek_point2; + public byte _res0; + public byte _res1; + public byte _res2; + public byte _res3; + public byte _res4; + public byte _res5; + public byte _res6; + public cd_seek(byte parameter_type, + int seek_point + ) { + this.command_code = 0x21; + this.parameter_type = parameter_type; + this.seek_point0 = (seek_point >> 16) & 0xff; + this.seek_point1 = (seek_point >> 8) & 0xff; + this.seek_point2 = (seek_point >> 0) & 0xff; + this._res0 = 0; + this._res1 = 0; + this._res2 = 0; + this._res3 = 0; + this._res4 = 0; + this._res5 = 0; + this._res6 = 0; + } + public get_byte(int ix) { + switch (ix) { + case 0: return command_code; + case 1: return parameter_type; + case 2: return seek_point0; + case 3: return seek_point1; + case 4: return seek_point2; + default: return 0; + } + } + } + public static class cd_scan { + public byte command_code; + public byte _res0; + public byte direction; + public byte speed; + public byte _res1; + public byte _res2; + public byte _res3; + public byte _res4; + public byte _res5; + public byte _res6; + public byte _res7; + public byte _res8; + public cd_scan(byte direction, + byte speed + ) { + this.command_code = 0x22; + this._res0 = 0; + this.direction = direction; + this.speed = speed; + this._res1 = 0; + this._res2 = 0; + this._res3 = 0; + this._res4 = 0; + this._res5 = 0; + this._res6 = 0; + this._res7 = 0; + this._res8 = 0; + } + public get_byte(int ix) { + switch (ix) { + case 0: return command_code; + case 2: return direction; + case 3: return speed; + default: return 0; + } + } + } + public static class cd_read { + public byte command_code; + public byte data; + public byte starting_address0; + public byte starting_address1; + public byte starting_address2; + public byte _res0; + public byte _res1; + public byte _res2; + public byte transfer_length0; + public byte transfer_length1; + public byte transfer_length2; + public byte _res3; + public cd_read(byte data, + int starting_address, + int transfer_length + ) { + this.command_code = 0x30; + this.data = data; + this.starting_address0 = (starting_address >> 16) & 0xff; + this.starting_address1 = (starting_address >> 8) & 0xff; + this.starting_address2 = (starting_address >> 0) & 0xff; + this._res0 = 0; + this._res1 = 0; + this._res2 = 0; + this.transfer_length0 = (transfer_length >> 16) & 0xff; + this.transfer_length1 = (transfer_length >> 8) & 0xff; + this.transfer_length2 = (transfer_length >> 0) & 0xff; + this._res3 = 0; + } + public get_byte(int ix) { + switch (ix) { + case 0: return command_code; + case 1: return data; + case 2: return starting_address0; + case 3: return starting_address1; + case 4: return starting_address2; + case 8: return transfer_length0; + case 9: return transfer_length1; + case 10: return transfer_length2; + default: return 0; + } + } + } + public static class cd_read2 { + public byte command_code; + public byte data; + public byte starting_address0; + public byte starting_address1; + public byte starting_address2; + public byte _res0; + public byte transfer_length0; + public byte transfer_length1; + public byte next_address0; + public byte next_address1; + public byte next_address2; + public byte _res1; + public cd_read2(byte data, + int starting_address, + int transfer_length, + int next_address + ) { + this.command_code = 0x31; + this.data = data; + this.starting_address0 = (starting_address >> 16) & 0xff; + this.starting_address1 = (starting_address >> 8) & 0xff; + this.starting_address2 = (starting_address >> 0) & 0xff; + this._res0 = 0; + this.transfer_length0 = (transfer_length >> 8) & 0xff; + this.transfer_length1 = (transfer_length >> 0) & 0xff; + this.next_address0 = (next_address >> 16) & 0xff; + this.next_address1 = (next_address >> 8) & 0xff; + this.next_address2 = (next_address >> 0) & 0xff; + this._res1 = 0; + } + public get_byte(int ix) { + switch (ix) { + case 0: return command_code; + case 1: return data; + case 2: return starting_address0; + case 3: return starting_address1; + case 4: return starting_address2; + case 6: return transfer_length0; + case 7: return transfer_length1; + case 8: return next_address0; + case 9: return next_address1; + case 10: return next_address2; + default: return 0; + } + } + } + public static class cd_scd { + public byte command_code; + public byte data_format; + public byte _res0; + public byte allocation_length0; + public byte allocation_length1; + public byte _res1; + public byte _res2; + public byte _res3; + public byte _res4; + public byte _res5; + public byte _res6; + public byte _res7; + public cd_scd(byte data_format, + int allocation_length + ) { + this.command_code = 0x40; + this.data_format = data_format; + this._res0 = 0; + this.allocation_length0 = (allocation_length >> 8) & 0xff; + this.allocation_length1 = (allocation_length >> 0) & 0xff; + this._res1 = 0; + this._res2 = 0; + this._res3 = 0; + this._res4 = 0; + this._res5 = 0; + this._res6 = 0; + this._res7 = 0; + } + public get_byte(int ix) { + switch (ix) { + case 0: return command_code; + case 1: return data_format; + case 3: return allocation_length0; + case 4: return allocation_length1; + default: return 0; + } + } + } +}