Skip to content

Commit 27a1b95

Browse files
authored
Support RGBDS 0.8.0 object version 10 (#2)
1 parent a28a7d5 commit 27a1b95

File tree

3 files changed

+89
-11
lines changed

3 files changed

+89
-11
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/lib.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! This crate allows working with [RGBDS] object files.
2-
//! Currently, only version 9 revisions 6–9 are supported, but more should be added in the
2+
//! Currently, only version 9 revisions 6–10 are supported, but more should be added in the
33
//! future.
44
//!
55
//! # Object file revision table
@@ -11,7 +11,10 @@
1111
//!
1212
//! RGBDS release | Object file format
1313
//! -------------------------------------------------------|-------------------
14-
//! [v0.6.0](https://rgbds.gbdev.io/docs/v0.?.?/rgbds.5) | v9 r9
14+
//! [v0.8.0](https://rgbds.gbdev.io/docs/v0.8.0/rgbds.5) | v9 r10
15+
//! [v0.7.0](https://rgbds.gbdev.io/docs/v0.7.0/rgbds.5) | v9 r9 (reported), v9 r10 (actual)
16+
//! [v0.6.1](https://rgbds.gbdev.io/docs/v0.6.1/rgbds.5) | v9 r9
17+
//! [v0.6.0](https://rgbds.gbdev.io/docs/v0.6.0/rgbds.5) | v9 r9
1518
//! [v0.5.1](https://rgbds.gbdev.io/docs/v0.5.1/rgbds.5) | v9 r8
1619
//! [v0.5.0](https://rgbds.gbdev.io/docs/v0.5.0/rgbds.5) | v9 r7
1720
//! [v0.4.2](https://rgbds.gbdev.io/docs/v0.4.2/rgbds.5) | v9 r6
@@ -48,6 +51,7 @@ use util::*;
4851
/// A RGBDS object file.
4952
#[derive(Debug)]
5053
pub struct Object {
54+
version: u8,
5155
revision: u32,
5256
fstack_nodes: Vec<Node>,
5357
symbols: Vec<Symbol>,
@@ -78,23 +82,25 @@ impl Object {
7882
"This does not appear to be a valid RGBDS object",
7983
));
8084
}
81-
if magic[3] != b'9' {
85+
86+
let version = magic[3];
87+
if version != b'9' {
8288
return Err(io::Error::new(
8389
io::ErrorKind::InvalidData,
8490
format!(
85-
"Object file version {} is not supported (only 9 is)",
86-
magic[3]
91+
"Object file version {} is not supported (must be 9)",
92+
version
8793
),
8894
));
8995
}
9096

9197
let revision = read_u32le(&mut input)?;
92-
if !(6..=9).contains(&revision) {
98+
if !(6..=10).contains(&revision) {
9399
return Err(io::Error::new(
94100
io::ErrorKind::InvalidData,
95101
format!(
96-
"Object file v9 revision {} is not supported (must be between 6 and 9)",
97-
revision
102+
"Object file {} revision {} is not supported (must be between 6 and 10)",
103+
version, revision
98104
),
99105
));
100106
}
@@ -104,6 +110,7 @@ impl Object {
104110
let nb_fstack_nodes = read_u32le(&mut input)?.try_into().unwrap();
105111

106112
let mut obj = Self {
113+
version,
107114
revision,
108115
fstack_nodes: Vec::with_capacity(nb_fstack_nodes),
109116
symbols: Vec::with_capacity(nb_symbols),
@@ -132,7 +139,7 @@ impl Object {
132139

133140
/// The object's version.
134141
pub fn version(&self) -> u8 {
135-
9
142+
self.version
136143
}
137144

138145
/// The object's revision.

src/rpn.rs

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,36 @@ use std::iter;
1717
#[derive(Debug)]
1818
pub struct RpnExpr(Vec<u8>);
1919

20+
/// A section memory type.
21+
#[derive(Debug, PartialEq)]
22+
pub enum SectType {
23+
Wram0,
24+
Vram,
25+
Romx,
26+
Rom0,
27+
Hram,
28+
Wramx,
29+
Sram,
30+
Oam,
31+
}
32+
impl SectType {
33+
/// The section type's name.
34+
pub fn name(&self) -> &'static str {
35+
use SectType::*;
36+
37+
match self {
38+
Wram0 => "WRAM0",
39+
Vram => "VRAM",
40+
Romx => "ROMX",
41+
Rom0 => "ROM0",
42+
Hram => "HRAM",
43+
Wramx => "WRAMX",
44+
Sram => "SRAM",
45+
Oam => "OAM",
46+
}
47+
}
48+
}
49+
2050
impl RpnExpr {
2151
/// Constructs a RPN expression from its byte serialization.
2252
/// This does not check the expression's correctness.
@@ -65,6 +95,24 @@ impl<'a> Iter<'a> {
6595
}
6696
}
6797
}
98+
99+
fn read_sect_type(&mut self) -> Option<SectType> {
100+
use SectType::*;
101+
102+
let val = match self.0.bytes().get(self.1) {
103+
Some(0) => Some(Wram0),
104+
Some(1) => Some(Vram),
105+
Some(2) => Some(Romx),
106+
Some(3) => Some(Rom0),
107+
Some(4) => Some(Hram),
108+
Some(5) => Some(Wramx),
109+
Some(6) => Some(Sram),
110+
Some(7) => Some(Oam),
111+
_ => None,
112+
};
113+
self.1 += 1;
114+
val
115+
}
68116
}
69117
impl<'a> Iterator for Iter<'a> {
70118
type Item = Result<RpnOp<'a>, RpnIterError>;
@@ -112,6 +160,12 @@ impl<'a> Iterator for Iter<'a> {
112160
0x54 => self
113161
.read_string()
114162
.map_or(err, |string| Ok(RpnOp::StartofSect(string))),
163+
0x55 => self
164+
.read_sect_type()
165+
.map_or(err, |sect_type| Ok(RpnOp::SizeofSectType(sect_type))),
166+
0x56 => self
167+
.read_sect_type()
168+
.map_or(err, |sect_type| Ok(RpnOp::StartofSectType(sect_type))),
115169
0x60 => Ok(RpnOp::HramCheck),
116170
0x61 => Ok(RpnOp::RstCheck),
117171
0x80 => self.read_u32().map_or(err, |id| Ok(RpnOp::Int(id))),
@@ -284,6 +338,10 @@ pub enum RpnOp<'a> {
284338
SizeofSect(&'a [u8]),
285339
/// `STARTOF("section")`
286340
StartofSect(&'a [u8]),
341+
/// `SIZEOF(SectionType)`
342+
SizeofSectType(SectType),
343+
/// `STARTOF(SectionType)`
344+
StartofSectType(SectType),
287345
/// HRAM check (check if the value is in HRAM range, then `& 0xFF`).
288346
HramCheck,
289347
/// `rst` check (check if the value is a `rst` target, then `| 0xC7`).
@@ -336,6 +394,8 @@ impl RpnOp<'_> {
336394
BankSelf => Literal,
337395
SizeofSect(..) => Literal,
338396
StartofSect(..) => Literal,
397+
SizeofSectType(..) => Literal,
398+
StartofSectType(..) => Literal,
339399
HramCheck => Unary,
340400
RstCheck => Unary,
341401
Int(..) => Literal,
@@ -363,7 +423,8 @@ impl RpnOp<'_> {
363423

364424
// There is no precedence for non-binary operators...
365425
Neg | Cpl | Not | BankSym(..) | BankSect(..) | BankSelf | SizeofSect(..)
366-
| StartofSect(..) | HramCheck | RstCheck | Int(..) | Sym(..) => unreachable!(),
426+
| StartofSect(..) | SizeofSectType(..) | StartofSectType(..) | HramCheck | RstCheck
427+
| Int(..) | Sym(..) => unreachable!(),
367428
}
368429
}
369430

@@ -381,7 +442,8 @@ impl RpnOp<'_> {
381442

382443
// There is no associativity for non-binary operators...
383444
Neg | Cpl | Not | BankSym(..) | BankSect(..) | BankSelf | SizeofSect(..)
384-
| StartofSect(..) | HramCheck | RstCheck | Int(..) | Sym(..) => unreachable!(),
445+
| StartofSect(..) | SizeofSectType(..) | StartofSectType(..) | HramCheck | RstCheck
446+
| Int(..) | Sym(..) => unreachable!(),
385447
}
386448
}
387449

@@ -444,6 +506,8 @@ impl Display for RpnOp<'_> {
444506
BankSelf => write!(fmt, "BANK(@)"),
445507
SizeofSect(name) => write!(fmt, "SIZEOF(\"{}\")", String::from_utf8_lossy(&name)),
446508
StartofSect(name) => write!(fmt, "STARTOF(\"{}\")", String::from_utf8_lossy(&name)),
509+
SizeofSectType(sect_type) => write!(fmt, "SIZEOF({})", sect_type.name()),
510+
StartofSectType(sect_type) => write!(fmt, "STARTOF({})", sect_type.name()),
447511
HramCheck => write!(fmt, "HRAM?"),
448512
RstCheck => write!(fmt, "RST?"),
449513
Int(val) => write!(fmt, "${:04x}", val),

0 commit comments

Comments
 (0)