Skip to content

Commit 722c207

Browse files
committed
add basic support for rgbds assembly
This adds basic support for assembling and linking Game Boy and Game Boy Color games with RGBDS's `rgbasm` and `rgblink`. This also adds knowledge of the Sharp SM83 CPU family, the 8080/Z80-like CPU used on the device's SoC.
1 parent b131b2d commit 722c207

File tree

17 files changed

+420
-1
lines changed

17 files changed

+420
-1
lines changed

ci/ciimage/arch/install.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pkgs=(
1515
doxygen vulkan-validation-layers openssh mercurial gtk-sharp-2 qt5-tools
1616
libwmf cmake netcdf-fortran openmpi nasm gnustep-base gettext
1717
python-lxml hotdoc rust-bindgen qt6-base qt6-tools wayland wayland-protocols
18+
rgbds
1819
# cuda
1920
)
2021

docs/markdown/Reference-tables.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ These are return values of the `get_id` (Compiler family) and
4949
| armasm | Microsoft Macro Assembler for ARM and AARCH64 (Since 0.64.0) | |
5050
| mwasmarm | Metrowerks Assembler for Embedded ARM | |
5151
| mwasmeppc | Metrowerks Assembler for Embedded PowerPC | |
52+
| rgbds | Rednex GameBoy Development System | |
5253

5354
## Linker ids
5455

@@ -80,6 +81,7 @@ These are return values of the `get_linker_id` method in a compiler object.
8081
| ccomp | CompCert used as the linker driver |
8182
| mwldarm | The Metrowerks Linker with the ARM interface, used with mwccarm only |
8283
| mwldeppc | The Metrowerks Linker with the PowerPC interface, used with mwcceppc only |
84+
| rgbds | Rednex GameBoy Development System |
8385

8486
For languages that don't have separate dynamic linkers such as C# and Java, the
8587
`get_linker_id` will return the compiler name.
@@ -132,6 +134,7 @@ set in the cross file.
132134
| s390 | IBM zSystem s390 |
133135
| s390x | IBM zSystem s390x |
134136
| sh4 | SuperH SH-4 |
137+
| sm83 | Sharp SM83 (GB/GBC) |
135138
| sparc | 32 bit SPARC |
136139
| sparc64 | SPARC v9 processor |
137140
| sw_64 | 64 bit sunway processor |
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
## Basic support for RGBDS assembly
2+
3+
Meson now provides basic support for the assembly
4+
and linking of Game Boy and Game Boy Color games
5+
with RGBDS.
6+
7+
Most projects will still need to call `rgbfix` as
8+
a `custom_target` as this time, unless they have
9+
correct header values in assembly source.

mesonbuild/compilers/asm.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,3 +310,44 @@ def get_instruction_set_args(self, instruction_set: str) -> T.Optional[T.List[st
310310
def sanity_check(self, work_dir: str, environment: 'Environment') -> None:
311311
if self.info.cpu_family not in {'ppc'}:
312312
raise EnvironmentException(f'ASM compiler {self.id!r} does not support {self.info.cpu_family} CPU family')
313+
314+
class RgbdsCompiler(Compiler):
315+
language = 'rgbds'
316+
317+
def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, info: MachineInfo,
318+
linker: DynamicLinker, exe_wrapper: T.Optional[ExternalProgram] = None,
319+
is_cross: bool = True):
320+
super().__init__([], exelist, version, for_machine, info, linker, is_cross=is_cross)
321+
self.id = 'rgbds'
322+
self.exe_wrapper = exe_wrapper
323+
324+
def needs_static_linker(self) -> bool:
325+
return True
326+
327+
def get_optimization_args(self, optimization_level: str) -> T.List[str]:
328+
return []
329+
330+
def get_output_args(self, outputname: str) -> T.List[str]:
331+
return ['-o', outputname]
332+
333+
def get_depfile_suffix(self) -> str:
334+
return 'd'
335+
336+
def get_include_args(self, path: str, is_system: bool) -> T.List[str]:
337+
if not path:
338+
path = '.'
339+
return ['-I' + path]
340+
341+
def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]:
342+
return ['-M', outfile, '-MQ', outtarget]
343+
344+
def sanity_check(self, work_dir: str, environment: 'Environment') -> None:
345+
if self.info.cpu_family != 'sm83':
346+
raise EnvironmentException(f'ASM compiler {self.id!r} does not support {self.info.cpu_family} CPU family')
347+
348+
def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str],
349+
build_dir: str) -> T.List[str]:
350+
for idx, i in enumerate(parameter_list):
351+
if i[:2] == '-I':
352+
parameter_list[idx] = i[:2] + os.path.normpath(os.path.join(build_dir, i[2:]))
353+
return parameter_list

mesonbuild/compilers/compilers.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
'cython': ('pyx', ),
7070
'nasm': ('asm', 'nasm',),
7171
'masm': ('masm',),
72+
'rgbds': ('asm',),
7273
}
7374
all_languages = lang_suffixes.keys()
7475
c_cpp_suffixes = {'h'}

mesonbuild/compilers/detect.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@
7979
defaults['gcc_static_linker'] = ['gcc-ar']
8080
defaults['clang_static_linker'] = ['llvm-ar']
8181
defaults['nasm'] = ['nasm', 'yasm']
82+
defaults['rgbasm'] = ['rgbasm']
83+
defaults['rgblink'] = ['rgblink']
8284

8385

8486
def compiler_from_language(env: 'Environment', lang: str, for_machine: MachineChoice) -> T.Optional[Compiler]:
@@ -98,6 +100,7 @@ def compiler_from_language(env: 'Environment', lang: str, for_machine: MachineCh
98100
'cython': detect_cython_compiler,
99101
'nasm': detect_nasm_compiler,
100102
'masm': detect_masm_compiler,
103+
'rgbds': detect_rgbds_compiler,
101104
}
102105
return lang_map[lang](env, for_machine) if lang in lang_map else None
103106

@@ -1353,6 +1356,40 @@ def detect_masm_compiler(env: 'Environment', for_machine: MachineChoice) -> Comp
13531356
_handle_exceptions(popen_exceptions, [comp])
13541357
raise EnvironmentException('Unreachable code (exception to make mypy happy)')
13551358

1359+
def detect_rgbds_compiler(env: Environment, for_machine: MachineChoice) -> Compiler:
1360+
from .asm import RgbdsCompiler
1361+
exelist = env.lookup_binary_entry(for_machine, 'rgbasm')
1362+
is_cross = env.is_cross_build(for_machine) # true, until Meson is ported to GB
1363+
info = env.machines[for_machine]
1364+
if exelist is None:
1365+
exelist = defaults['rgbasm']
1366+
1367+
try:
1368+
output = Popen_safe([exelist[0], '--version'])[1]
1369+
except OSError:
1370+
raise EnvironmentalException('Could not execute RGBDS assembler "{}"'.format(''.join(exelist)))
1371+
1372+
version = search_version(output)
1373+
linker = _detect_rgblink(env, for_machine)
1374+
comp = RgbdsCompiler(exelist, version, for_machine, info, linker, env.exe_wrapper, is_cross)
1375+
env.coredata.add_lang_args(comp.language, RgbdsCompiler, for_machine, env)
1376+
1377+
return comp
1378+
1379+
def _detect_rgblink(env: Environment, for_machine: MachineChoice) -> DynamicLinker:
1380+
from ..linkers.linkers import RgbdsLinker
1381+
exelist = env.lookup_binary_entry(for_machine, 'rgblink')
1382+
if exelist is None:
1383+
exelist = defaults['rgblink']
1384+
1385+
try:
1386+
output = Popen_safe([exelist[0], '--version'])[1]
1387+
except OSError:
1388+
raise EnvironmentalException('Could not execute RGBDS linker"{}"'.format(''.join(exelist)))
1389+
1390+
version = search_version(output)
1391+
return RgbdsLinker(exelist, for_machine, '', [], version=version)
1392+
13561393
# GNU/Clang defines and version
13571394
# =============================
13581395

mesonbuild/envconfig.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
's390',
5858
's390x',
5959
'sh4',
60+
'sm83',
6061
'sparc',
6162
'sparc64',
6263
'sw_64',

mesonbuild/linkers/linkers.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1660,3 +1660,16 @@ class MetrowerksLinkerARM(MetrowerksLinker):
16601660

16611661
class MetrowerksLinkerEmbeddedPowerPC(MetrowerksLinker):
16621662
id = 'mwldeppc'
1663+
1664+
1665+
class RgbdsLinker(DynamicLinker):
1666+
id = 'rgblink'
1667+
1668+
def get_allow_undefined_args(self) -> T.List[str]:
1669+
return []
1670+
1671+
def get_output_args(self, outputname: str) -> T.List[str]:
1672+
return ['-o', outputname]
1673+
1674+
def get_search_args(self, dirname: str) -> T.List[str]:
1675+
return []

run_project_tests.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ class ArgumentType(CompilerArgumentType):
7979
'keyval', 'platform-osx', 'platform-windows', 'platform-linux',
8080
'java', 'C#', 'vala', 'cython', 'rust', 'd', 'objective c', 'objective c++',
8181
'fortran', 'swift', 'cuda', 'python3', 'python', 'fpga', 'frameworks', 'nasm', 'wasm', 'wayland',
82-
'format',
82+
'format', 'rgbds'
8383
]
8484

8585

@@ -1136,6 +1136,7 @@ def __init__(self, category: str, subdir: str, skip: bool = False, stdout_mandat
11361136
TestCategory('wasm', 'wasm', shutil.which('emcc') is None or backend is not Backend.ninja),
11371137
TestCategory('wayland', 'wayland', should_skip_wayland()),
11381138
TestCategory('format', 'format'),
1139+
TestCategory('rgbds', 'rgbds', shutil.which('rgbasm') is None)
11391140
]
11401141

11411142
categories = [t.category for t in all_tests]
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[binaries]
2+
c = 'gcc'
3+
strip = 'false'
4+
5+
[host_machine]
6+
system = 'dmg'
7+
cpu_family = 'sm83'
8+
cpu = 'sm8320'
9+
endian = 'little'

0 commit comments

Comments
 (0)