Update all docs and test generator to match verified assembler opcodes

- README.md: Complete project overview with plugin status
- ARCHITECTURE.md: Fixed register tables (CNTR in REG1, not REG2)
- GETTING_STARTED.md: r2-native workflow, removed Python disasm refs
- PRACTICAL_EXAMPLE.md: Uses verified open21xx opcodes with bit layouts
- ROM_ANALYSIS_WALKTHROUGH.md: Updated format detection and r2 commands
- r2plugin/README.md: Simplified, points to assembler test ROM
- gen_isa_test.py: All opcodes from open21xx assembler with labels
This commit is contained in:
Siggi
2026-04-22 18:46:54 +00:00
parent c8fba73574
commit 29dc1f1bd2
7 changed files with 380 additions and 200 deletions

View File

@@ -1,35 +1,102 @@
"""Generate an ISA test ROM from assembler-verified opcodes.
The opcodes below were produced by assembling isa_test.dsp with
the open21xx toolchain (as219x + ld21) and extracting the int_pm
section from the resulting ELF. They serve as ground truth for
validating the radare2 disassembler plugin.
"""
import os
import sys
def write_ins(f, ins_list):
"""Write 24-bit instructions to the file in Big Endian format."""
for ins in ins_list:
f.write(bytes([(ins >> 16) & 0xFF, (ins >> 8) & 0xFF, ins & 0xFF]))
def gen_isa_test_rom():
"""Generates a test ROM with various ADSP-219x instruction types."""
# Use path relative to the script's location
# Verified opcodes from open21xx assembler output.
# Source: examples/isa_test.dsp -> as219x -> ld21 -> dd
VERIFIED_OPCODES = [
# Type 30: NOP
(0x000000, "NOP"),
# Type 6: Dreg = Imm16
(0x412340, "AX0 = 0x1234"),
(0x456781, "AX1 = 0x5678"),
(0x4AAAA4, "AY0 = 0xAAAA"),
(0x440002, "MX0 = 0x4000"),
(0x420006, "MY0 = 0x2000"),
# Type 7: Reg1 = Imm16
(0x501000, "I0 = 0x0100"),
(0x502001, "I1 = 0x0200"),
(0x303000, "I4 = 0x0300"),
(0x500014, "M0 = 1"),
(0x500015, "M1 = 1"),
(0x5FFFF7, "M3 = -1"),
(0x300014, "M4 = 1"),
(0x500008, "L0 = 0"),
(0x300008, "L4 = 0"),
(0x3000AE, "CNTR = 10"),
# Type 17: Reg = Reg
(0x0D00A0, "AR = AX0"),
(0x0D00B1, "SI = AX1"),
(0x0D00E2, "MR0 = MX0"),
# Type 9: Compute (ALU)
(0x22600F, "AR = AX0 + AY0"),
(0x22E00F, "AR = AX0 - AY0"),
(0x23800F, "AR = AX0 AND AY0"),
(0x23A00F, "AR = AX0 OR AY0"),
(0x23C00F, "AR = AX0 XOR AY0"),
(0x22780F, "AR = PASS AX0"),
(0x23380F, "AR = -AX0"),
(0x23E00F, "AR = ABS AX0"),
# Type 9: Compute (MAC)
(0x20800F, "MR = MX0 * MY0 (SS)"),
# Type 10a: Jump (unconditional, 16-bit addr)
(0x1C0010, "JUMP _skip1"),
(0x000000, "NOP"),
# Type 10: Jump (conditional, 13-bit addr)
(0x180010, "IF EQ JUMP _skip2"),
(0x000000, "NOP"),
# Type 10a: Call + Jump
(0x1C0024, "CALL _sub1"),
(0x1C0030, "JUMP _after_sub"),
(0x000000, "NOP (in sub)"),
# Type 20: RTS
(0x0A00F0, "RTS"),
(0x000000, "NOP (after sub)"),
# Type 7: CNTR for loop
(0x30004E, "CNTR = 4"),
# Type 11: DO UNTIL
(0x16002E, "DO _loop_end UNTIL CE"),
(0x000000, "NOP (loop body)"),
(0x000000, "NOP (loop end)"),
# Type 15: Shift Immediate
(0x0F0B04, "SR = LSHIFT SI BY 4 (HI)"),
(0x0F4BFE, "SR = ASHIFT SI BY -2 (HI)"),
# Type 18: Mode Control
(0x0C0800, "DIS AR_SAT"),
(0x0C0C00, "ENA AR_SAT"),
# Type 25: Saturate MR
(0x030000, "SAT MR"),
# Type 33: Reg3 = short immediate
(0x100005, "SE = 0"),
# Type 10a: Infinite loop
(0x1C0000, "JUMP _halt"),
]
def main():
base_dir = os.path.dirname(os.path.abspath(__file__))
rom_p = os.path.join(base_dir, "test_roms", "isa_test.bin")
os.makedirs(os.path.dirname(rom_p), exist_ok=True)
instructions = [
0x000000, 0x000215, 0xC00000, 0xCC9A55, 0x801234, 0x815678, 0x606800,
0x412340, 0x4ABCDD, 0x511110, 0x344440, 0x226810, 0x206800, 0x18100F,
0x1A2000, (0x1C1234 << 4), 0x16610F, 0x124000, 0x128010, 0x0F0050,
0x0EE000, 0x0D4400, 0x0C0001, 0x0C1000, 0x0B000F, 0x0A000F, 0x0A800F,
0x018000, 0x010100, 0x07E340, 0x120000, 0x038000, 0x03F000, 0x030000,
0x040010, 0x081050, 0x150040, 0x06D100, 0x06C200, 0x06000F, 0x123456, 0x077001
]
try:
with open(rom_p, "wb") as f:
write_ins(f, instructions)
print(f"Generated ISA test ROM with {len(instructions)} instructions at: {rom_p}")
except OSError as e:
print(f"Error writing ROM file: {e}", file=sys.stderr)
sys.exit(1)
rom_path = os.path.join(base_dir, "test_roms", "isa_test.bin")
os.makedirs(os.path.dirname(rom_path), exist_ok=True)
with open(rom_path, "wb") as f:
for opcode, _label in VERIFIED_OPCODES:
f.write(bytes([
(opcode >> 16) & 0xFF,
(opcode >> 8) & 0xFF,
opcode & 0xFF,
]))
print("Generated ISA test ROM with %d instructions at: %s"
% (len(VERIFIED_OPCODES), rom_path))
if __name__ == "__main__":
gen_isa_test_rom()
main()