2022-03-13 13:33:19 -04:00
|
|
|
import logging
|
2022-04-05 09:19:04 -04:00
|
|
|
from dataclasses import dataclass, field
|
2023-11-13 08:23:12 -05:00
|
|
|
from typing import Any, Dict, OrderedDict
|
2024-03-29 16:16:48 +00:00
|
|
|
from pathlib import Path
|
|
|
|
|
import functools
|
2022-04-05 09:19:04 -04:00
|
|
|
|
2025-01-28 22:00:44 +01:00
|
|
|
from coreapp.flags import (
|
|
|
|
|
COMMON_DIFF_FLAGS,
|
|
|
|
|
COMMON_MIPS_DIFF_FLAGS,
|
|
|
|
|
COMMON_MSDOS_DIFF_FLAGS,
|
|
|
|
|
Flags,
|
|
|
|
|
)
|
2023-11-13 08:23:12 -05:00
|
|
|
from coreapp.models.preset import Preset
|
|
|
|
|
from coreapp.models.scratch import Scratch
|
2023-01-27 20:18:10 +09:00
|
|
|
from rest_framework.exceptions import APIException
|
2022-03-13 13:33:19 -04:00
|
|
|
|
2023-11-13 08:23:12 -05:00
|
|
|
from coreapp.serializers import PresetSerializer
|
2022-03-13 13:33:19 -04:00
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class Platform:
|
|
|
|
|
id: str
|
|
|
|
|
name: str
|
|
|
|
|
description: str
|
|
|
|
|
arch: str
|
|
|
|
|
assemble_cmd: str
|
|
|
|
|
objdump_cmd: str
|
|
|
|
|
nm_cmd: str
|
2022-11-15 00:21:38 +00:00
|
|
|
diff_flags: Flags = field(default_factory=lambda: COMMON_DIFF_FLAGS, hash=False)
|
2022-04-05 09:19:04 -04:00
|
|
|
supports_objdump_disassemble: bool = False # TODO turn into objdump flag
|
2024-03-16 18:31:46 +00:00
|
|
|
has_decompiler: bool = False
|
2022-03-13 13:33:19 -04:00
|
|
|
|
2024-03-29 16:16:48 +00:00
|
|
|
@property
|
|
|
|
|
@functools.lru_cache()
|
|
|
|
|
def asm_prelude(self) -> str:
|
|
|
|
|
asm_prelude_path: Path = Path(__file__).parent / "asm_preludes" / f"{self.id}.s"
|
|
|
|
|
if asm_prelude_path.is_file():
|
|
|
|
|
return asm_prelude_path.read_text()
|
|
|
|
|
return ""
|
|
|
|
|
|
2023-11-13 08:23:12 -05:00
|
|
|
def get_num_scratches(self) -> int:
|
|
|
|
|
return Scratch.objects.filter(platform=self.id).count()
|
|
|
|
|
|
|
|
|
|
def to_json(
|
|
|
|
|
self, include_presets: bool = True, include_num_scratches: bool = False
|
|
|
|
|
) -> Dict[str, Any]:
|
|
|
|
|
ret: Dict[str, Any] = {
|
|
|
|
|
"id": self.id,
|
|
|
|
|
"name": self.name,
|
|
|
|
|
"description": self.description,
|
|
|
|
|
"arch": self.arch,
|
2024-03-16 18:31:46 +00:00
|
|
|
"has_decompiler": self.has_decompiler,
|
2023-11-13 08:23:12 -05:00
|
|
|
}
|
|
|
|
|
if include_presets:
|
|
|
|
|
ret["presets"] = [
|
|
|
|
|
PresetSerializer(p).data
|
2023-11-22 00:41:26 +09:00
|
|
|
for p in Preset.objects.filter(platform=self.id).order_by("name")
|
2023-11-13 08:23:12 -05:00
|
|
|
]
|
|
|
|
|
if include_num_scratches:
|
|
|
|
|
ret["num_scratches"] = self.get_num_scratches()
|
|
|
|
|
return ret
|
|
|
|
|
|
2022-03-13 13:33:19 -04:00
|
|
|
|
|
|
|
|
def from_id(platform_id: str) -> Platform:
|
|
|
|
|
if platform_id not in _platforms:
|
2023-01-27 20:18:10 +09:00
|
|
|
raise APIException(f"Unknown platform: {platform_id}")
|
2022-03-13 13:33:19 -04:00
|
|
|
return _platforms[platform_id]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DUMMY = Platform(
|
|
|
|
|
id="dummy",
|
|
|
|
|
name="Dummy System",
|
|
|
|
|
description="DMY",
|
|
|
|
|
arch="dummy",
|
|
|
|
|
assemble_cmd='echo "assembled("$INPUT")" > "$OUTPUT"',
|
|
|
|
|
objdump_cmd="echo",
|
|
|
|
|
nm_cmd="echo",
|
|
|
|
|
)
|
|
|
|
|
|
2023-07-03 11:06:14 +01:00
|
|
|
MSDOS = Platform(
|
|
|
|
|
id="msdos",
|
|
|
|
|
name="Microsoft DOS",
|
|
|
|
|
description="x86",
|
2025-01-28 22:00:44 +01:00
|
|
|
arch="x86",
|
2024-07-02 20:37:14 +03:00
|
|
|
assemble_cmd='jwasm -c -Fo"$OUTPUT" -Fi"$PRELUDE" "$INPUT"',
|
2025-02-12 13:00:43 +01:00
|
|
|
objdump_cmd="omf-objdump --no-objects",
|
2023-09-20 08:37:35 +01:00
|
|
|
nm_cmd="omf-nm",
|
2025-01-28 22:00:44 +01:00
|
|
|
supports_objdump_disassemble=True,
|
|
|
|
|
diff_flags=COMMON_DIFF_FLAGS + COMMON_MSDOS_DIFF_FLAGS,
|
2023-07-03 11:06:14 +01:00
|
|
|
)
|
|
|
|
|
|
2024-02-26 00:33:32 +09:00
|
|
|
WIN32 = Platform(
|
|
|
|
|
id="win32",
|
|
|
|
|
name="Windows (9x/NT)",
|
2023-09-03 23:12:07 +01:00
|
|
|
description="x86 (32bit)",
|
|
|
|
|
arch="i686",
|
2024-04-08 19:20:15 +01:00
|
|
|
assemble_cmd='i686-w64-mingw32-as --32 -mmnemonic=intel -msyntax=intel -mnaked-reg -o "$OUTPUT" "$PRELUDE" "$INPUT"',
|
2024-02-27 11:59:42 -07:00
|
|
|
objdump_cmd="i686-w64-mingw32-objdump",
|
|
|
|
|
nm_cmd="i686-w64-mingw32-nm",
|
2023-09-03 23:12:07 +01:00
|
|
|
)
|
|
|
|
|
|
2022-03-13 13:33:19 -04:00
|
|
|
SWITCH = Platform(
|
|
|
|
|
id="switch",
|
|
|
|
|
name="Nintendo Switch",
|
|
|
|
|
description="ARMv8-A",
|
|
|
|
|
arch="aarch64",
|
2024-04-08 19:20:15 +01:00
|
|
|
assemble_cmd='aarch64-linux-gnu-as -mcpu=cortex-a57+fp+simd+crypto+crc -o "$OUTPUT" "$PRELUDE" "$INPUT"',
|
2022-03-13 13:33:19 -04:00
|
|
|
objdump_cmd="aarch64-linux-gnu-objdump",
|
|
|
|
|
nm_cmd="aarch64-linux-gnu-nm",
|
|
|
|
|
supports_objdump_disassemble=True,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
N64 = Platform(
|
|
|
|
|
id="n64",
|
|
|
|
|
name="Nintendo 64",
|
|
|
|
|
description="MIPS (big-endian)",
|
|
|
|
|
arch="mips",
|
2024-04-08 19:20:15 +01:00
|
|
|
assemble_cmd='mips-linux-gnu-as -march=vr4300 -mabi=32 -o "$OUTPUT" "$PRELUDE" "$INPUT"',
|
2022-03-13 13:33:19 -04:00
|
|
|
objdump_cmd="mips-linux-gnu-objdump",
|
|
|
|
|
nm_cmd="mips-linux-gnu-nm",
|
2022-11-15 00:21:38 +00:00
|
|
|
diff_flags=COMMON_DIFF_FLAGS + COMMON_MIPS_DIFF_FLAGS,
|
2024-03-16 18:31:46 +00:00
|
|
|
has_decompiler=True,
|
2022-12-07 06:47:55 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
IRIX = Platform(
|
|
|
|
|
id="irix",
|
|
|
|
|
name="IRIX",
|
|
|
|
|
description="MIPS (big-endian, PIC)",
|
|
|
|
|
arch="mips",
|
2024-04-08 19:20:15 +01:00
|
|
|
assemble_cmd='mips-linux-gnu-as -march=vr4300 -mabi=32 -KPIC -o "$OUTPUT" "$PRELUDE" "$INPUT"',
|
2022-12-07 06:47:55 +00:00
|
|
|
objdump_cmd="mips-linux-gnu-objdump",
|
|
|
|
|
nm_cmd="mips-linux-gnu-nm",
|
|
|
|
|
diff_flags=COMMON_DIFF_FLAGS + COMMON_MIPS_DIFF_FLAGS,
|
2024-03-16 18:31:46 +00:00
|
|
|
has_decompiler=True,
|
2022-03-13 13:33:19 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
PS1 = Platform(
|
|
|
|
|
id="ps1",
|
|
|
|
|
name="PlayStation",
|
|
|
|
|
description="MIPS (little-endian)",
|
|
|
|
|
arch="mipsel",
|
2024-04-08 19:20:15 +01:00
|
|
|
assemble_cmd='mips-linux-gnu-as -EL -march=r3000 -mabi=32 -o "$OUTPUT" "$PRELUDE" "$INPUT"',
|
2022-03-13 13:33:19 -04:00
|
|
|
objdump_cmd="mips-linux-gnu-objdump",
|
|
|
|
|
nm_cmd="mips-linux-gnu-nm",
|
2022-12-25 02:02:43 -03:00
|
|
|
diff_flags=COMMON_DIFF_FLAGS + COMMON_MIPS_DIFF_FLAGS,
|
2024-03-16 18:31:46 +00:00
|
|
|
has_decompiler=True,
|
2023-04-09 00:27:01 -04:00
|
|
|
)
|
|
|
|
|
|
2024-02-15 14:17:26 +00:00
|
|
|
PSP = Platform(
|
|
|
|
|
id="psp",
|
|
|
|
|
name="PlayStation Portable",
|
|
|
|
|
description="MIPS (little-endian)",
|
|
|
|
|
arch="mipsel:4000",
|
2024-06-04 10:45:18 -07:00
|
|
|
assemble_cmd='mips-ps2-decompals-as -EL -march=gs464 -mabi=32 -o "$OUTPUT" "$PRELUDE" "$INPUT"',
|
|
|
|
|
objdump_cmd="mips-ps2-decompals-objdump",
|
|
|
|
|
nm_cmd="mips-ps2-decompals-nm",
|
2024-02-15 14:17:26 +00:00
|
|
|
diff_flags=COMMON_DIFF_FLAGS + COMMON_MIPS_DIFF_FLAGS,
|
2024-03-16 18:31:46 +00:00
|
|
|
has_decompiler=True,
|
2024-02-15 14:17:26 +00:00
|
|
|
)
|
|
|
|
|
|
2023-04-09 00:27:01 -04:00
|
|
|
SATURN = Platform(
|
|
|
|
|
id="saturn",
|
|
|
|
|
name="Saturn",
|
|
|
|
|
description="SH2 (big-endian)",
|
|
|
|
|
arch="sh2",
|
2024-04-08 19:20:15 +01:00
|
|
|
assemble_cmd='sh-elf-as --isa=sh2 --big -o "$OUTPUT" "$PRELUDE" "$INPUT"',
|
2023-04-09 00:27:01 -04:00
|
|
|
objdump_cmd="sh-elf-objdump",
|
|
|
|
|
nm_cmd="sh-elf-nm",
|
|
|
|
|
diff_flags=COMMON_DIFF_FLAGS,
|
2022-03-13 13:33:19 -04:00
|
|
|
)
|
|
|
|
|
|
2024-06-10 14:38:13 +03:00
|
|
|
DREAMCAST = Platform(
|
|
|
|
|
id="dreamcast",
|
|
|
|
|
name="Dreamcast",
|
|
|
|
|
description="SH4 (little-endian)",
|
|
|
|
|
arch="sh4",
|
|
|
|
|
assemble_cmd='sh-elf-as --isa=sh4 --little --relax -o "$OUTPUT" "$PRELUDE" "$INPUT"',
|
|
|
|
|
objdump_cmd="sh-elf-objdump",
|
|
|
|
|
nm_cmd="sh-elf-nm",
|
|
|
|
|
diff_flags=COMMON_DIFF_FLAGS,
|
|
|
|
|
has_decompiler=False,
|
|
|
|
|
)
|
|
|
|
|
|
2022-03-13 13:33:19 -04:00
|
|
|
PS2 = Platform(
|
|
|
|
|
id="ps2",
|
|
|
|
|
name="PlayStation 2",
|
|
|
|
|
description="MIPS (little-endian)",
|
2022-11-15 07:06:56 -05:00
|
|
|
arch="mipsee",
|
2024-08-15 07:20:22 -05:00
|
|
|
assemble_cmd='mips-ps2-decompals-as -EL -march=r5900 -o "$OUTPUT" "$PRELUDE" "$INPUT"',
|
2024-04-01 12:38:25 +02:00
|
|
|
objdump_cmd="mips-ps2-decompals-objdump",
|
|
|
|
|
nm_cmd="mips-ps2-decompals-nm",
|
2022-12-25 02:02:43 -03:00
|
|
|
diff_flags=COMMON_DIFF_FLAGS + COMMON_MIPS_DIFF_FLAGS,
|
2024-03-16 18:31:46 +00:00
|
|
|
has_decompiler=True,
|
2022-03-13 13:33:19 -04:00
|
|
|
)
|
|
|
|
|
|
2022-06-05 16:06:37 -06:00
|
|
|
MACOSX = Platform(
|
|
|
|
|
id="macosx",
|
|
|
|
|
name="Mac OS X",
|
|
|
|
|
description="PowerPC",
|
|
|
|
|
arch="ppc",
|
2024-04-08 19:20:15 +01:00
|
|
|
assemble_cmd='powerpc-linux-gnu-as -o "$OUTPUT" "$PRELUDE" "$INPUT"',
|
2022-06-05 16:06:37 -06:00
|
|
|
objdump_cmd="powerpc-linux-gnu-objdump",
|
|
|
|
|
nm_cmd="powerpc-linux-gnu-nm",
|
|
|
|
|
)
|
|
|
|
|
|
2022-03-13 13:33:19 -04:00
|
|
|
GC_WII = Platform(
|
|
|
|
|
id="gc_wii",
|
|
|
|
|
name="GameCube / Wii",
|
|
|
|
|
description="PowerPC",
|
|
|
|
|
arch="ppc",
|
2024-04-08 19:20:15 +01:00
|
|
|
assemble_cmd='powerpc-eabi-as -mgekko -o "$OUTPUT" "$PRELUDE" "$INPUT"',
|
2024-03-03 05:08:02 -07:00
|
|
|
objdump_cmd="powerpc-eabi-objdump -M broadway",
|
|
|
|
|
nm_cmd="powerpc-eabi-nm",
|
2024-03-16 18:31:46 +00:00
|
|
|
has_decompiler=True,
|
2022-03-13 13:33:19 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
NDS_ARM9 = Platform(
|
|
|
|
|
id="nds_arm9",
|
|
|
|
|
name="Nintendo DS",
|
2022-10-26 19:10:23 +09:00
|
|
|
description="ARMv5TE",
|
2022-03-13 13:33:19 -04:00
|
|
|
arch="arm32",
|
2024-04-08 19:20:15 +01:00
|
|
|
assemble_cmd='sed -i -e "s/;/;@/" "$INPUT" && arm-none-eabi-as -march=armv5te -mthumb -o "$OUTPUT" "$PRELUDE" "$INPUT"',
|
2022-03-13 13:33:19 -04:00
|
|
|
objdump_cmd="arm-none-eabi-objdump",
|
|
|
|
|
nm_cmd="arm-none-eabi-nm",
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
GBA = Platform(
|
|
|
|
|
id="gba",
|
|
|
|
|
name="Game Boy Advance",
|
|
|
|
|
description="ARMv4T",
|
|
|
|
|
arch="arm32",
|
2024-04-08 19:20:15 +01:00
|
|
|
assemble_cmd='sed -i -e "s/;/;@/" "$INPUT" && arm-none-eabi-as -mcpu=arm7tdmi -mthumb -o "$OUTPUT" "$PRELUDE" "$INPUT"',
|
2022-03-13 13:33:19 -04:00
|
|
|
objdump_cmd="arm-none-eabi-objdump",
|
|
|
|
|
nm_cmd="arm-none-eabi-nm",
|
|
|
|
|
)
|
|
|
|
|
|
2022-08-11 09:26:16 +03:00
|
|
|
N3DS = Platform(
|
|
|
|
|
id="n3ds",
|
|
|
|
|
name="Nintendo 3DS",
|
|
|
|
|
description="ARMv6K",
|
|
|
|
|
arch="arm32",
|
2024-04-08 19:20:15 +01:00
|
|
|
assemble_cmd='sed -i -e "s/;/;@/" "$INPUT" && arm-none-eabi-as -mfpu=vfpv2 -march=armv6k -o "$OUTPUT" "$PRELUDE" "$INPUT"',
|
2022-08-11 09:26:16 +03:00
|
|
|
objdump_cmd="arm-none-eabi-objdump",
|
|
|
|
|
nm_cmd="arm-none-eabi-nm",
|
|
|
|
|
)
|
|
|
|
|
|
2022-03-13 13:33:19 -04:00
|
|
|
_platforms: OrderedDict[str, Platform] = OrderedDict(
|
|
|
|
|
{
|
|
|
|
|
"dummy": DUMMY,
|
2022-12-07 06:47:55 +00:00
|
|
|
"irix": IRIX,
|
2022-03-13 13:33:19 -04:00
|
|
|
"n64": N64,
|
|
|
|
|
"gc_wii": GC_WII,
|
2023-09-12 06:40:08 +09:00
|
|
|
"switch": SWITCH,
|
2022-03-13 13:33:19 -04:00
|
|
|
"gba": GBA,
|
2023-09-12 06:40:08 +09:00
|
|
|
"nds_arm9": NDS_ARM9,
|
|
|
|
|
"n3ds": N3DS,
|
|
|
|
|
"ps1": PS1,
|
|
|
|
|
"ps2": PS2,
|
2024-02-15 14:17:26 +00:00
|
|
|
"psp": PSP,
|
2023-09-12 06:40:08 +09:00
|
|
|
"saturn": SATURN,
|
2024-06-10 14:38:13 +03:00
|
|
|
"dreamcast": DREAMCAST,
|
2022-06-05 16:06:37 -06:00
|
|
|
"macosx": MACOSX,
|
2023-07-03 11:06:14 +01:00
|
|
|
"msdos": MSDOS,
|
2024-02-26 00:33:32 +09:00
|
|
|
"win32": WIN32,
|
2022-03-13 13:33:19 -04:00
|
|
|
}
|
|
|
|
|
)
|