diff --git a/backend/src/parser.rs b/backend/src/parser.rs index 4f7c544ab..bee741f40 100644 --- a/backend/src/parser.rs +++ b/backend/src/parser.rs @@ -21,15 +21,12 @@ pub use self::{ coil::Coil, dmg_stamp::DmgStamp, eeprom::Eeprom, - gbs_dol::GbsDol, gen1_soc::{Gen1Soc, Gen1SocKind}, gen2_soc::{Gen2Soc, Gen2SocKind}, - icd2::Icd2, lcd_chip::LcdChip, lcd_screen::LcdScreen, mapper::{Huc1Version, Mapper, MapperType, Mbc1Version, Mbc2Version, Mbc3Version}, mask_rom::MaskRom, - sgb_rom::SgbRom, tama::{Tama, TamaType}, }; @@ -53,12 +50,10 @@ pub mod crystal_8mihz; pub mod dmg_stamp; pub mod eeprom; pub mod fujitsu; -pub mod gbs_dol; pub mod gen1_soc; pub mod gen2_soc; pub mod hynix; pub mod hyundai; -pub mod icd2; pub mod lcd_chip; pub mod lcd_screen; pub mod lgs; @@ -68,6 +63,7 @@ pub mod mask_rom; pub mod mitsubishi; pub mod mitsumi; pub mod nec; +pub mod oki; pub mod oxy_u4; pub mod oxy_u5; pub mod rohm; @@ -313,6 +309,20 @@ mod for_nom { recognize(fold_many_m_n(min, max, satisfy(f), || (), |_, _| ())) } + pub fn satisfy_m_n_complete<'a, E: ParseError<&'a str>>( + min: usize, + max: usize, + f: impl Fn(char) -> bool, + ) -> impl Parser<&'a str, &'a str, E> { + recognize(fold_many_m_n( + min, + max, + nom::character::complete::satisfy(f), + || (), + |_, _| (), + )) + } + pub fn alnum_uppers<'a, E: ParseError<&'a str>>( count: usize, ) -> impl Parser<&'a str, &'a str, E> { @@ -655,3 +665,16 @@ pub fn ags_pmic_old() -> &'static impl LabelParser { pub fn fram_sop_28_3v3() -> &'static impl LabelParser { multi_parser!(GenericPart, &fujitsu::FUJITSU_MB85R256,) } + +pub fn gbs_dol() -> &'static impl LabelParser { + &nec::NEC_GBS_DOL +} + +pub fn icd2() -> &'static impl LabelParser { + multi_parser!( + GenericPart, + &rohm::ROHM_ICD2_R, + &nec::NEC_ICD2_N, + &nec::NEC_ICD2_R + ) +} diff --git a/backend/src/parser/agb_soc_bga.rs b/backend/src/parser/agb_soc_bga.rs index 8b9ebe3b3..487aafafe 100644 --- a/backend/src/parser/agb_soc_bga.rs +++ b/backend/src/parser/agb_soc_bga.rs @@ -2,10 +2,10 @@ // // SPDX-License-Identifier: MIT -use super::{week2, year2, ChipYearWeek, LabelParser}; -use crate::macros::single_parser; +use super::{week2, year2, GenericPart, LabelParser}; +use crate::{macros::single_parser, parser::PartDateCode}; -pub type AgbSoc = ChipYearWeek; +pub type AgbSoc = GenericPart; /// ``` /// use gbhwdb_backend::parser::{self, LabelParser}; @@ -19,8 +19,10 @@ pub fn agb_soc_bga() -> &'static impl LabelParser { Ok(AgbSoc { kind: c[3].to_owned(), manufacturer: None, - year: Some(year2(&c[1])?), - week: Some(week2(&c[2])?), + date_code: Some(PartDateCode::YearWeek { + year: year2(&c[1])?, + week: week2(&c[2])?, + }), }) }, ) diff --git a/backend/src/parser/fujitsu.rs b/backend/src/parser/fujitsu.rs index 7266e2fb4..de6cb4fb2 100644 --- a/backend/src/parser/fujitsu.rs +++ b/backend/src/parser/fujitsu.rs @@ -7,7 +7,7 @@ use nom::{ bytes::streaming::tag, character::{complete::one_of, streaming::char}, combinator::{opt, recognize}, - sequence::tuple, + sequence::{terminated, tuple}, Parser as _, }; @@ -110,3 +110,28 @@ pub static FUJITSU_MASK_ROM: NomParser = NomParser { .parse(input) }, }; + +/// Fujitsu SGB mask ROM +/// +/// ``` +/// use gbhwdb_backend::parser::{self, LabelParser}; +/// assert!(parser::fujitsu::FUJITSU_SGB_ROM.parse("SYS-SGB-2 © 1994 Nintendo 9429 R77").is_ok()); +/// ``` +pub static FUJITSU_SGB_ROM: NomParser = NomParser { + name: "Fujitsu SGB ROM", + f: |input| { + tuple(( + terminated(tag("SYS-SGB-2"), tag(" © 1994 Nintendo ")), + year2_week2, + char(' '), + uppers(1).and(digits(2)), + )) + .map(|(rom_id, date_code, _, _)| MaskRom { + rom_id: String::from(rom_id), + manufacturer: Some(Manufacturer::Fujitsu), + chip_type: None, + date_code: Some(date_code), + }) + .parse(input) + }, +}; diff --git a/backend/src/parser/gbs_dol.rs b/backend/src/parser/gbs_dol.rs deleted file mode 100644 index 7639fd124..000000000 --- a/backend/src/parser/gbs_dol.rs +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-FileCopyrightText: 2017-2023 Joonas Javanainen -// -// SPDX-License-Identifier: MIT - -use super::{week2, year2, ChipYearWeek, LabelParser}; -use crate::macros::single_parser; - -pub type GbsDol = ChipYearWeek; - -/// ``` -/// use gbhwdb_backend::parser::{self, LabelParser}; -/// assert!(parser::gbs_dol::unknown().parse("Nintendo GBS-DOL 011 0623L3001").is_ok()); -/// ``` -pub fn unknown() -> &'static impl LabelParser { - single_parser!( - GbsDol, - r#"^Nintendo\ GBS-DOL\ 011\ ([0-9]{2})([0-9]{2})[A-Z][0-9]{4}$"#, - move |c| { - Ok(GbsDol { - kind: "GBS-DOL".to_owned(), - manufacturer: None, - year: Some(year2(&c[1])?), - week: Some(week2(&c[2])?), - }) - }, - ) -} - -pub fn gbs_dol() -> &'static impl LabelParser { - unknown() -} diff --git a/backend/src/parser/icd2.rs b/backend/src/parser/icd2.rs deleted file mode 100644 index b2527e43b..000000000 --- a/backend/src/parser/icd2.rs +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-FileCopyrightText: 2017-2023 Joonas Javanainen -// -// SPDX-License-Identifier: MIT - -use super::{week2, year1, year2, ChipYearWeek, LabelParser}; -use crate::macros::{multi_parser, single_parser}; - -pub type Icd2 = ChipYearWeek; - -/// ``` -/// use gbhwdb_backend::parser::{self, LabelParser}; -/// assert!(parser::icd2::unknown().parse("Nintendo ICD2-R 435 129").is_ok()); -/// ``` -pub fn unknown() -> &'static impl LabelParser { - single_parser!( - Icd2, - r#"^Nintendo\ (ICD2-[NR])\ ([0-9])([0-9]{2})\ [0-9]{3}$"#, - move |c| { - Ok(Icd2 { - kind: c[1].to_owned(), - manufacturer: None, - year: Some(year1(&c[2])?), - week: Some(week2(&c[3])?), - }) - }, - ) -} - -/// ``` -/// use gbhwdb_backend::parser::{self, LabelParser}; -/// assert!(parser::icd2::unknown2().parse("Nintendo ICD2-N 9415KX226 D93115").is_ok()); -/// ``` -pub fn unknown2() -> &'static impl LabelParser { - single_parser!( - Icd2, - r#"^Nintendo\ (ICD2-[NR])\ ([0-9]{2})\ ?([0-9]{2})[A-Z]{2}[0-9]{3}\ (D93115|D93128)$"#, - move |c| { - Ok(Icd2 { - kind: c[1].to_owned(), - manufacturer: None, - year: Some(year2(&c[2])?), - week: Some(week2(&c[3])?), - }) - }, - ) -} - -pub fn icd2() -> &'static impl LabelParser { - multi_parser!(Icd2, unknown(), unknown2()) -} diff --git a/backend/src/parser/mask_rom.rs b/backend/src/parser/mask_rom.rs index f3bf0af06..7bbeb3d88 100644 --- a/backend/src/parser/mask_rom.rs +++ b/backend/src/parser/mask_rom.rs @@ -2,10 +2,10 @@ // // SPDX-License-Identifier: MIT -use super::{week2, year1, year2, LabelParser, Manufacturer, ParsedData, PartDateCode}; +use super::{week2, year2, LabelParser, Manufacturer, ParsedData, PartDateCode}; use crate::{ macros::{multi_parser, single_parser}, - parser::{fujitsu::FUJITSU_MASK_ROM, macronix, nec, toshiba}, + parser::{fujitsu::FUJITSU_MASK_ROM, macronix, nec, oki, toshiba}, }; #[derive(Clone, Debug, Eq, PartialEq)] @@ -92,76 +92,6 @@ pub fn sharp3() -> &'static impl LabelParser { ) } -/// Very old OKI mask ROM chip -/// -/// ``` -/// use gbhwdb_backend::parser::{self, LabelParser}; -/// assert!(parser::mask_rom::oki_old().parse("DMG-QXA-0 OKI JAPAN B0 03 X0 02").is_ok()); -/// ``` -pub fn oki_old() -> &'static impl LabelParser { - single_parser!( - MaskRom, - r#"^(DMG-[[:alnum:]]{3}-[0-9])\ OKI\ JAPAN\ [[:alnum:]]{2}\ [0-9]{2}\ [[:alnum:]]{2}\ [0-9]{2}$"#, - move |c| { - Ok(MaskRom { - rom_id: c[1].to_owned(), - manufacturer: Some(Manufacturer::Oki), - chip_type: None, - date_code: None, - }) - }, - ) -} - -/// OKI Semiconductor MSM534011E / MSM538011E mask ROM -/// -/// ``` -/// use gbhwdb_backend::parser::{self, LabelParser}; -/// assert!(parser::mask_rom::oki_msm53x011e().parse("DMG-AM6J-0 F1 M538011E-36 9085401").is_ok()); -/// assert!(parser::mask_rom::oki_msm53x011e().parse("CGB-ADME-0 E1 M534011E-09 841232A").is_ok()); -/// ``` -pub fn oki_msm53x011e() -> &'static impl LabelParser { - single_parser!( - MaskRom, - r#"^((DMG|CGB)-[[:alnum:]]{3,4}-[0-9])\ [A-Z][0-9]\ (M53[48]011E)-[[:alnum:]]{2}\ ([0-9])([0-9]{2})[0-9]{3}[[:alnum:]]$"#, - move |c| { - Ok(MaskRom { - rom_id: c[1].to_owned(), - manufacturer: Some(Manufacturer::Oki), - chip_type: Some(format!("MS{}", &c[3])), - date_code: Some(PartDateCode::YearWeek { - year: year1(&c[4])?, - week: week2(&c[5])?, - }), - }) - }, - ) -} - -/// OKI Semiconductor MR531614G mask ROM -/// -/// ``` -/// use gbhwdb_backend::parser::{self, LabelParser}; -/// assert!(parser::mask_rom::oki_mr531614g().parse("CGB-BPTE-0 G2 R531614G-44 044232E").is_ok()); -/// ``` -pub fn oki_mr531614g() -> &'static impl LabelParser { - single_parser!( - MaskRom, - r#"^((DMG|CGB)-[[:alnum:]]{3,4}-[0-9])\ [A-Z][0-9]\ (R531614G)-[[:alnum:]]{2}\ ([0-9])([0-9]{2})[0-9]{3}[[:alnum:]]$"#, - move |c| { - Ok(MaskRom { - rom_id: c[1].to_owned(), - manufacturer: Some(Manufacturer::Oki), - chip_type: Some(format!("M{}", &c[3])), - date_code: Some(PartDateCode::YearWeek { - year: year1(&c[4])?, - week: week2(&c[5])?, - }), - }) - }, - ) -} - /// Glop top mask ROM. /// /// Probably manufactured by Sharp (?) @@ -230,58 +160,6 @@ pub fn samsung2() -> &'static impl LabelParser { ) } -/// OKI MR26V TSOP-II-44 Mask ROM -/// -/// ``` -/// use gbhwdb_backend::parser::{self, LabelParser}; -/// assert!(parser::mask_rom::oki_mr26v().parse("AGB-TCHK-1 H2 R26V3210F-087 244A239").is_ok()); -/// assert!(parser::mask_rom::oki_mr26v().parse("AGB-AXVJ-0 I2 R26V6414G-0A7 243A262").is_ok()); -/// assert!(parser::mask_rom::oki_mr26v().parse("AGB-BR4J-0 I2 R26V6415G-02L 427ABA3").is_ok()); -/// assert!(parser::mask_rom::oki_mr26v().parse("AGB-BR3P-0 H2 R26V3211F-0T6 442ABAJJ").is_ok()); -/// ``` -pub fn oki_mr26v() -> &'static impl LabelParser { - single_parser!( - MaskRom, - r#"^(AGB-[[:alnum:]]{4}-[0-9])\ [A-Z][0-9]\ (R26V[0-9]{4}[A-Z])-[0-9][[:alnum:]][[:alnum:]]\ ([0-9])([0-9]{2})[A-Z][[:alnum:]]{3}[A-Z]?$"#, - move |c| { - Ok(MaskRom { - rom_id: c[1].to_owned(), - manufacturer: Some(Manufacturer::Oki), - chip_type: Some(format!("M{}", &c[2])), - date_code: Some(PartDateCode::YearWeek { - year: year1(&c[3])?, - week: week2(&c[4])?, - }), - }) - }, - ) -} - -/// OKI MR27V TSOP-II-44 Mask ROM -/// -/// ``` -/// use gbhwdb_backend::parser::{self, LabelParser}; -/// assert!(parser::mask_rom::oki_mr27v().parse("AGB-AXPS-1 J2 R27V12813M-0C7 6145BARJ").is_ok()); -/// assert!(parser::mask_rom::oki_mr27v().parse("AGB-FADP-0 F2 R27V810F-059 4475BB4J").is_ok()); -/// assert!(parser::mask_rom::oki_mr27v().parse("AGB-U32P-0 J2 R27V12813M-0D2 5175204J").is_ok()); -/// ``` -pub fn oki_mr27v() -> &'static impl LabelParser { - single_parser!( - MaskRom, - r#"^(AGB-[[:alnum:]]{4}-[0-9])\ [A-Z][0-9]\ (R27V[0-9]{3,5}[A-Z])-[0-9][[:alnum:]][0-9]\ ([0-9])[0-9]{3}[[:alnum:]]{3}[A-Z]$"#, - move |c| { - Ok(MaskRom { - rom_id: c[1].to_owned(), - manufacturer: Some(Manufacturer::Oki), - chip_type: Some(format!("M{}", &c[2])), - date_code: Some(PartDateCode::Year { - year: year1(&c[3])?, - }), - }) - }, - ) -} - /// Magnachip AC23V Mask ROM /// /// ``` @@ -375,8 +253,13 @@ pub fn agb_mask_rom_tsop_ii_44() -> &'static impl LabelParser { ¯onix::MACRONIX_MX23L12806, ¯onix::MACRONIX_MX23L12807, ¯onix::MACRONIX_MX23L25607, - oki_mr26v(), - oki_mr27v(), + &oki::OKI_MR26V3210, + &oki::OKI_MR26V3211, + &oki::OKI_MR26V6413, + &oki::OKI_MR26V6414, + &oki::OKI_MR26V6415, + &oki::OKI_MR27V810, + &oki::OKI_MR27V12813, ) } @@ -393,8 +276,8 @@ pub fn mask_rom_sop_32() -> &'static impl LabelParser { ¯onix::MACRONIX_MX23C4002, ¯onix::MACRONIX_MX23C8003, ¯onix::MACRONIX_MX23C8005, - oki_msm53x011e(), - oki_mr531614g(), + &oki::OKI_MSM534011, + &oki::OKI_MSM538011, &nec::NEC_UPD23C1001E, &nec::NEC_UPD23C2001E, &nec::NEC_UPD23C4001E, @@ -408,7 +291,6 @@ pub fn mask_rom_sop_32() -> &'static impl LabelParser { samsung(), samsung2(), &FUJITSU_MASK_ROM, - oki_old(), ) } @@ -417,11 +299,8 @@ pub fn mask_rom_tsop_i_32() -> &'static impl LabelParser { MaskRom, sharp(), ¯onix::MACRONIX_MX23C8006, - oki_msm53x011e(), - oki_mr531614g(), samsung(), samsung2(), - oki_old(), ) } @@ -433,12 +312,10 @@ pub fn mask_rom_tsop_ii_44_5v() -> &'static impl LabelParser { sharp3(), ¯onix::MACRONIX_MX23C1603, ¯onix::MACRONIX_MX23C3203, - oki_msm53x011e(), - oki_mr531614g(), + &oki::OKI_MR531614, &nec::NEC_UPD23C16019W, samsung(), samsung2(), - oki_old(), ) } @@ -448,10 +325,8 @@ pub fn mask_rom_qfp_44() -> &'static impl LabelParser { sharp(), sharp2(), sharp3(), - oki_msm53x011e(), - oki_mr531614g(), samsung(), samsung2(), - oki_old(), + &oki::OKI_OLD_MASK_ROM, ) } diff --git a/backend/src/parser/nec.rs b/backend/src/parser/nec.rs index d7f25a5e8..6977107f3 100644 --- a/backend/src/parser/nec.rs +++ b/backend/src/parser/nec.rs @@ -8,13 +8,13 @@ use nom::{ character::streaming::char, combinator::{cond, recognize, value}, error::ParseError, - sequence::tuple, - Parser, + sequence::{delimited, preceded, terminated, tuple}, + IResult, Parser, }; use super::{ - for_nom::{cgb_rom_code, digits, dmg_rom_code, uppers}, - GenericPart, MaskRom, + for_nom::{alnum_uppers, cgb_rom_code, digits, dmg_rom_code, uppers}, + GenericPart, MaskRom, PartDateCode, }; use crate::parser::{for_nom::year2_week2, Manufacturer, NomParser}; @@ -44,9 +44,9 @@ pub static NEC_UPD442012A_X: NomParser = NomParser { tag("MJH"), ))), char(' '), - tuple((year2_week2, uppers(1), digits(4))), + date_and_lot_code, )) - .map(|(_, kind, _, (date_code, _, _))| GenericPart { + .map(|(_, kind, _, date_code)| GenericPart { kind: String::from(kind), manufacturer: Some(Manufacturer::Nec), date_code: Some(date_code), @@ -80,9 +80,9 @@ pub static NEC_UPD442012L_X: NomParser = NomParser { tag("MJH"), ))), char(' '), - tuple((year2_week2, uppers(1), digits(4))), + date_and_lot_code, )) - .map(|(_, kind, _, (date_code, _, _))| GenericPart { + .map(|(_, kind, _, date_code)| GenericPart { kind: String::from(kind), manufacturer: Some(Manufacturer::Nec), date_code: Some(date_code), @@ -107,10 +107,10 @@ fn upd23c<'a, E: ParseError<&'a str>>( )) .and(char('-').and(uppers(1)).and(digits(2))), char(' '), - tuple((year2_week2, uppers(1), digits(4))), + date_and_lot_code, )) .map( - |(rom_id, _, _, _, ((series, kind, package), _), _, (date_code, _, _))| MaskRom { + |(rom_id, _, _, _, ((series, kind, package), _), _, date_code)| MaskRom { rom_id: String::from(rom_id), manufacturer: Some(Manufacturer::Nec), chip_type: Some(format!("{series}{kind}{package}")), @@ -136,10 +136,10 @@ fn upd23c_old<'a, E: ParseError<&'a str>>( )) .and(char('-').and(uppers(1)).and(digits(2))), char(' '), - tuple((year2_week2, uppers(1), digits(4))), + date_and_lot_code, )) .map( - |(_, rom_id, _, _, _, ((series, kind, package), _), _, (date_code, _, _))| MaskRom { + |(_, rom_id, _, _, _, ((series, kind, package), _), _, date_code)| MaskRom { rom_id: String::from(rom_id), manufacturer: Some(Manufacturer::Nec), chip_type: Some(format!("{series}{kind}{package}")), @@ -167,10 +167,10 @@ fn upd23c_licensed<'a, E: ParseError<&'a str>>( )) .and(char('-').and(uppers(1)).and(digits(2))), char(' '), - tuple((year2_week2, uppers(1), digits(4))), + date_and_lot_code, )) .map( - move |(_, _, rom_id, _, _, ((series, kind, package), _), _, (date_code, _, _))| MaskRom { + move |(_, _, rom_id, _, _, ((series, kind, package), _), _, date_code)| MaskRom { rom_id: String::from(rom_id), manufacturer: Some(manufacturer), chip_type: Some(format!("{series}{kind}{package}")), @@ -319,6 +319,116 @@ pub static MANI_UPD23C4001E: NomParser = NomParser { }, }; +/// NEC GBS-DOL +/// +/// ``` +/// use gbhwdb_backend::parser::{self, LabelParser}; +/// assert!(parser::nec::NEC_GBS_DOL.parse("Nintendo GBS-DOL 011 0623L3001").is_ok()); +/// ``` +pub static NEC_GBS_DOL: NomParser = NomParser { + name: "NEC GBS-DOL", + f: |input| { + tuple(( + delimited(tag("Nintendo "), tag("GBS-DOL"), tag(" 011")), + char(' '), + date_and_lot_code, + )) + .map(|(kind, _, date_code)| GenericPart { + kind: String::from(kind), + manufacturer: Some(Manufacturer::Nec), + date_code: Some(date_code), + }) + .parse(input) + }, +}; + +/// NEC ICD2-N +/// +/// ``` +/// use gbhwdb_backend::parser::{self, LabelParser}; +/// assert!(parser::nec::NEC_ICD2_N.parse("Nintendo ICD2-N 9415KX226 D93115").is_ok()); +/// ``` +pub static NEC_ICD2_N: NomParser = NomParser { + name: "NEC ICD2-N", + f: |input| { + tuple(( + preceded(tag("Nintendo "), tag("ICD2-N")), + char(' '), + date_and_lot_code, + tag(" D93115"), + )) + .map(|(kind, _, date_code, _)| GenericPart { + kind: String::from(kind), + manufacturer: Some(Manufacturer::Nec), + date_code: Some(date_code), + }) + .parse(input) + }, +}; + +/// NEC ICD2-R +/// +/// ``` +/// use gbhwdb_backend::parser::{self, LabelParser}; +/// assert!(parser::nec::NEC_ICD2_R.parse("Nintendo ICD2-R 9802EX006 D93128").is_ok()); +/// ``` +pub static NEC_ICD2_R: NomParser = NomParser { + name: "NEC ICD2-R", + f: |input| { + tuple(( + preceded(tag("Nintendo "), tag("ICD2-R")), + char(' '), + date_and_lot_code, + tag(" D93128"), + )) + .map(|(kind, _, date_code, _)| GenericPart { + kind: String::from(kind), + manufacturer: Some(Manufacturer::Nec), + date_code: Some(date_code), + }) + .parse(input) + }, +}; + +/// NEC SGB mask ROM +/// +/// ``` +/// use gbhwdb_backend::parser::{self, LabelParser}; +/// assert!(parser::nec::NEC_SGB_ROM.parse("© 1994 Nintendo SYS-SGB-NT N-2001EGW-J56 9414X9013").is_ok()); +/// ``` +pub static NEC_SGB_ROM: NomParser = NomParser { + name: "NEC SGB ROM", + f: |input| { + tuple(( + preceded(tag("© 1994 Nintendo "), tag("SYS-SGB-NT")), + char(' '), + tuple(( + value("μPD23C", tag("N-")), + tag("2001E"), + tag(Package::Sop32.code()), + )) + .and(char('-').and(uppers(1)).and(digits(2))), + char(' '), + date_and_lot_code, + )) + .map( + |(rom_id, _, ((series, kind, package), _), _, date_code)| MaskRom { + rom_id: String::from(rom_id), + chip_type: Some(format!("{series}{kind}{package}")), + manufacturer: Some(Manufacturer::Nec), + date_code: Some(date_code), + }, + ) + .parse(input) + }, +}; + +fn date_and_lot_code<'a, E: ParseError<&'a str>>( + input: &'a str, +) -> IResult<&'a str, PartDateCode, E> { + terminated(year2_week2, uppers(1).and(alnum_uppers(1)).and(digits(3))).parse(input) +} + #[derive(Copy, Clone, Debug, PartialEq, Eq)] enum Package { Sop32, diff --git a/backend/src/parser/oki.rs b/backend/src/parser/oki.rs new file mode 100644 index 000000000..34b95a217 --- /dev/null +++ b/backend/src/parser/oki.rs @@ -0,0 +1,235 @@ +// SPDX-FileCopyrightText: Joonas Javanainen +// +// SPDX-License-Identifier: MIT + +use nom::{ + branch::alt, bytes::streaming::tag, character::streaming::char, error::ParseError, + sequence::tuple, Parser, +}; + +use super::{ + for_nom::{ + agb_rom_code, alnum_uppers, cgb_rom_code, digits, dmg_rom_code, satisfy_m_n_complete, + uppers, year1_week2, + }, + MaskRom, +}; +use crate::parser::{Manufacturer, NomParser}; + +/// OKI old mask ROM chip (QFP-44, 5V) +/// +/// ``` +/// use gbhwdb_backend::parser::{self, LabelParser}; +/// assert!(parser::oki::OKI_OLD_MASK_ROM.parse("DMG-QXA-0 OKI JAPAN B0 03 X0 02").is_ok()); +/// ``` +pub static OKI_OLD_MASK_ROM: NomParser = NomParser { + name: "OKI old mask ROM", + f: |input| { + tuple(( + dmg_rom_code(), + tag(" OKI JAPAN "), + alnum_uppers(2), + char(' '), + digits(2), + char(' '), + alnum_uppers(2), + char(' '), + digits(2), + )) + .map(|(rom_id, _, _, _, _, _, _, _, _)| MaskRom { + rom_id: String::from(rom_id), + manufacturer: Some(Manufacturer::Oki), + chip_type: None, + date_code: None, + }) + .parse(input) + }, +}; + +fn gb<'a, E: ParseError<&'a str>>( + prefix: &'static str, + chip_type: &'static str, +) -> impl Parser<&'a str, MaskRom, E> { + tuple(( + alt((dmg_rom_code(), cgb_rom_code())), + char(' '), + uppers(1).and(digits(1)), + char(' '), + tag(chip_type).and(char('-').and(alnum_uppers(2))), + char(' '), + tuple((year1_week2, alnum_uppers(1), digits(2), alnum_uppers(1))), + )) + .map( + move |(rom_id, _, _, _, (kind, _), _, (date_code, _, _, _))| MaskRom { + rom_id: String::from(rom_id), + manufacturer: Some(Manufacturer::Oki), + chip_type: Some(format!("{prefix}{kind}")), + date_code: Some(date_code), + }, + ) +} + +/// OKI MSM534011 (SOP-32, 5V) +/// +/// ``` +/// use gbhwdb_backend::parser::{self, LabelParser}; +/// assert!(parser::oki::OKI_MSM534011.parse("CGB-ADME-0 E1 M534011E-09 841232A").is_ok()); +/// ``` +pub static OKI_MSM534011: NomParser = NomParser { + name: "OKI MSM534011", + f: |input| gb("MS", "M534011E").parse(input), +}; + +/// OKI MSM538011 (SOP-32, 5V) +/// +/// ``` +/// use gbhwdb_backend::parser::{self, LabelParser}; +/// assert!(parser::oki::OKI_MSM538011.parse("DMG-AM6J-0 F1 M538011E-36 9085401").is_ok()); +/// assert!(parser::oki::OKI_MSM538011.parse("CGB-BJWP-0 F1 M538011E-4D 0475408").is_ok()); +/// ``` +pub static OKI_MSM538011: NomParser = NomParser { + name: "OKI MSM538011", + f: |input| gb("MS", "M538011E").parse(input), +}; + +/// OKI MR531614 (TSOP-II-44, 5V) +/// +/// ``` +/// use gbhwdb_backend::parser::{self, LabelParser}; +/// assert!(parser::oki::OKI_MR531614.parse("CGB-BPTE-0 G2 R531614G-44 044232E").is_ok()); +/// ``` +pub static OKI_MR531614: NomParser = NomParser { + name: "OKI MR531614", + f: |input| gb("M", "R531614G").parse(input), +}; + +fn gba<'a, E: ParseError<&'a str>>( + prefix: &'static str, + chip_type: &'static str, +) -> impl Parser<&'a str, MaskRom, E> { + tuple(( + agb_rom_code(), + char(' '), + uppers(1).and(digits(1)), + char(' '), + tag(chip_type).and(char('-').and(char('0').and(alnum_uppers(2)))), + char(' '), + tuple(( + year1_week2, + satisfy_m_n_complete(4, 5, |c| c.is_ascii_uppercase() || c.is_ascii_digit()), + )), + )) + .map( + move |(rom_id, _, _, _, (kind, _), _, (date_code, _))| MaskRom { + rom_id: String::from(rom_id), + manufacturer: Some(Manufacturer::Oki), + chip_type: Some(format!("{prefix}{kind}")), + date_code: Some(date_code), + }, + ) +} + +/// OKI MR26V3210 (TSOP-II-44, 3.3V) +/// +/// ``` +/// use gbhwdb_backend::parser::{self, LabelParser}; +/// assert!(parser::oki::OKI_MR26V3210.parse("AGB-TCHK-1 H2 R26V3210F-087 244A239").is_ok()); +/// ``` +pub static OKI_MR26V3210: NomParser = NomParser { + name: "OKI MR26V3210", + f: |input| gba("M", "R26V3210F").parse(input), +}; + +/// OKI MR26V3211 (TSOP-II-44, 3.3V) +/// +/// ``` +/// use gbhwdb_backend::parser::{self, LabelParser}; +/// assert!(parser::oki::OKI_MR26V3211.parse("AGB-BR3P-0 H2 R26V3211F-0T6 442ABAJJ").is_ok()); +/// ``` +pub static OKI_MR26V3211: NomParser = NomParser { + name: "OKI MR26V3211", + f: |input| gba("M", "R26V3211F").parse(input), +}; + +/// OKI MR26V6413 (TSOP-II-44, 3.3V) +/// +/// ``` +/// use gbhwdb_backend::parser::{self, LabelParser}; +/// assert!(parser::oki::OKI_MR26V6413.parse("AGB-A7HJ-0 I2 R26V6413G-0A9 242A273").is_ok()); +/// ``` +pub static OKI_MR26V6413: NomParser = NomParser { + name: "OKI MR26V6413", + f: |input| gba("M", "R26V6413G").parse(input), +}; + +/// OKI MR26V6414 (TSOP-II-44, 3.3V) +/// +/// ``` +/// use gbhwdb_backend::parser::{self, LabelParser}; +/// assert!(parser::oki::OKI_MR26V6414.parse("AGB-AXVJ-0 I2 R26V6414G-0A7 243A262").is_ok()); +/// ``` +pub static OKI_MR26V6414: NomParser = NomParser { + name: "OKI MR26V6414", + f: |input| gba("M", "R26V6414G").parse(input), +}; + +/// OKI MR26V6415 (TSOP-II-44, 3.3V) +/// +/// ``` +/// use gbhwdb_backend::parser::{self, LabelParser}; +/// assert!(parser::oki::OKI_MR26V6415.parse("AGB-BR4J-0 I2 R26V6415G-02L 427ABA3").is_ok()); +/// ``` +pub static OKI_MR26V6415: NomParser = NomParser { + name: "OKI MR26V6415", + f: |input| gba("M", "R26V6415G").parse(input), +}; + +/// OKI MR27V810 (TSOP-II-44, 3.3V) +/// +/// ``` +/// use gbhwdb_backend::parser::{self, LabelParser}; +/// assert!(parser::oki::OKI_MR27V810.parse("AGB-FADP-0 F2 R27V810F-059 4475BB4J").is_ok()); +/// ``` +pub static OKI_MR27V810: NomParser = NomParser { + name: "OKI MR27V810", + f: |input| gba("M", "R27V810F").parse(input), +}; + +/// OKI MR27V12813 (TSOP-II-44, 3.3V) +/// +/// ``` +/// use gbhwdb_backend::parser::{self, LabelParser}; +/// assert!(parser::oki::OKI_MR27V12813.parse("AGB-AXPS-1 J2 R27V12813M-0C7 6145BARJ").is_ok()); +/// ``` +pub static OKI_MR27V12813: NomParser = NomParser { + name: "OKI MR27V12813", + f: |input| gba("M", "R27V12813M").parse(input), +}; + +/// OKI SGB mask ROM +/// +/// ``` +/// use gbhwdb_backend::parser::{self, LabelParser}; +/// assert!(parser::oki::OKI_SGB_ROM.parse("SYS-SGB2-10 © 1998 Nintendo M534011E-05 8012354").is_ok()); +/// ``` +pub static OKI_SGB_ROM: NomParser = NomParser { + name: "OKI SGB ROM", + f: |input| { + tuple(( + tag("SYS-SGB2-10"), + tag(" © 1998 Nintendo "), + tag("M534011E").and(char('-').and(alnum_uppers(2))), + char(' '), + tuple((year1_week2, alnum_uppers(1), digits(2), alnum_uppers(1))), + )) + .map( + move |(rom_id, _, (kind, _), _, (date_code, _, _, _))| MaskRom { + rom_id: String::from(rom_id), + manufacturer: Some(Manufacturer::Oki), + chip_type: Some(format!("MS{kind}")), + date_code: Some(date_code), + }, + ) + .parse(input) + }, +}; diff --git a/backend/src/parser/rohm.rs b/backend/src/parser/rohm.rs index bd22eee91..4eba06368 100644 --- a/backend/src/parser/rohm.rs +++ b/backend/src/parser/rohm.rs @@ -7,7 +7,7 @@ use nom::{ bytes::streaming::tag, character::streaming::{char, one_of}, combinator::recognize, - sequence::tuple, + sequence::{preceded, tuple}, Parser as _, }; @@ -152,7 +152,7 @@ pub static ROHM_9753: NomParser = NomParser { }, }; -/// BH7835AFS AGB amplifier +/// ROHM BH7835AFS AGB amplifier /// /// ``` /// use gbhwdb_backend::parser::{self, LabelParser}; @@ -177,3 +177,29 @@ pub static ROHM_BH7835AFS: NomParser = NomParser { .parse(input) }, }; + +/// ROHM ICD2-R +/// +/// ``` +/// use gbhwdb_backend::parser::{self, LabelParser}; +/// assert!(parser::rohm::ROHM_ICD2_R.parse("Nintendo ICD2-R 435 179").is_ok()); +/// ``` +pub static ROHM_ICD2_R: NomParser = NomParser { + name: "ROHM ICD2_R", + f: |input| { + tuple(( + preceded(tag("Nintendo "), tag("ICD2-R")), + char(' '), + year1_week2, + char(' '), + alnum_uppers(1), + digits(2), + )) + .map(|(kind, _, date_code, _, _, _)| GenericPart { + kind: String::from(kind), + manufacturer: Some(Manufacturer::Rohm), + date_code: Some(date_code), + }) + .parse(input) + }, +}; diff --git a/backend/src/parser/sgb_rom.rs b/backend/src/parser/sgb_rom.rs index ad879a9fe..f0fcb88a0 100644 --- a/backend/src/parser/sgb_rom.rs +++ b/backend/src/parser/sgb_rom.rs @@ -2,58 +2,29 @@ // // SPDX-License-Identifier: MIT -use super::{week2, year1, year2, LabelParser, Manufacturer, ParsedData, Year}; +use super::{week2, year2, LabelParser, Manufacturer}; use crate::{ macros::{multi_parser, single_parser}, - time::Week, + parser::{fujitsu, nec, oki, toshiba, MaskRom, PartDateCode}, }; -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct SgbRom { - pub rom_id: String, - pub manufacturer: Option, - pub chip_type: Option, - pub year: Option, - pub week: Option, -} - -impl ParsedData for SgbRom {} - -/// ``` -/// use gbhwdb_backend::parser::{self, LabelParser}; -/// assert!(parser::sgb_rom::unknown().parse("SYS-SGB-2 © 1994 Nintendo 9429 R77").is_ok()); -/// ``` -pub fn unknown() -> &'static impl LabelParser { - single_parser!( - SgbRom, - r#"^(SYS-SGB-(NT|2))\ ©\ 1994\ Nintendo\ ([0-9]{2})([0-9]{2})\ [A-Z][0-9]{2}$"#, - move |c| { - Ok(SgbRom { - rom_id: c[1].to_owned(), - manufacturer: None, - chip_type: None, - year: Some(year2(&c[3])?), - week: Some(week2(&c[4])?), - }) - }, - ) -} - /// ``` /// use gbhwdb_backend::parser::{self, LabelParser}; /// assert!(parser::sgb_rom::unknown2().parse("SYS-SGB-2 © 1994 Nintendo 9423 E").is_ok()); /// ``` -pub fn unknown2() -> &'static impl LabelParser { +pub fn unknown2() -> &'static impl LabelParser { single_parser!( - SgbRom, + MaskRom, r#"^(SYS-SGB-(NT|2))\ ©\ 1994\ Nintendo\ ([0-9]{2})([0-9]{2})\ [A-Z]$"#, move |c| { - Ok(SgbRom { + Ok(MaskRom { rom_id: c[1].to_owned(), manufacturer: None, chip_type: None, - year: Some(year2(&c[3])?), - week: Some(week2(&c[4])?), + date_code: Some(PartDateCode::YearWeek { + year: year2(&c[3])?, + week: week2(&c[4])?, + }), }) }, ) @@ -63,59 +34,16 @@ pub fn unknown2() -> &'static impl LabelParser { /// use gbhwdb_backend::parser::{self, LabelParser}; /// assert!(parser::sgb_rom::unknown3().parse("SYS-SGB-2 JAPAN © 1994 Nintendo 427A2 A04 NND").is_ok()); /// ``` -pub fn unknown3() -> &'static impl LabelParser { +pub fn unknown3() -> &'static impl LabelParser { single_parser!( - SgbRom, + MaskRom, r#"^(SYS-SGB-(NT|2))\ JAPAN\ ©\ 1994\ Nintendo\ [[:alnum:]]{5}\ [[:alnum:]]{3}\ [A-Z]{3}$"#, move |c| { - Ok(SgbRom { + Ok(MaskRom { rom_id: c[1].to_owned(), manufacturer: None, chip_type: None, - year: None, - week: None, - }) - }, - ) -} - -/// ``` -/// use gbhwdb_backend::parser::{self, LabelParser}; -/// assert!(parser::sgb_rom::unknown4().parse("© 1994 Nintendo SYS-SGB-NT N-2001EGW-J56 9414X9013").is_ok()); -/// ``` -pub fn unknown4() -> &'static impl LabelParser { - single_parser!( - SgbRom, - r#"^©\ 1994\ Nintendo\ (SYS-SGB-(NT|2))\ (N-[0-9]{4}[[:alnum:]]{3,4})-[A-Z][0-9]{2}\ ([0-9]{2})([0-9]{2})[A-Z][0-9]{4}$"#, - move |c| { - Ok(SgbRom { - rom_id: c[1].to_owned(), - manufacturer: None, - chip_type: Some(c[3].to_owned()), - year: Some(year2(&c[4])?), - week: Some(week2(&c[5])?), - }) - }, - ) -} - -/// Toshiba SGB ROM -/// -/// ``` -/// use gbhwdb_backend::parser::{self, LabelParser}; -/// assert!(parser::sgb_rom::toshiba().parse("SYS-SGB-2 © 1994 Nintendo TC532000BF-N807 JAPAN 9431EAI").is_ok()); -/// ``` -pub fn toshiba() -> &'static impl LabelParser { - single_parser!( - SgbRom, - r#"^(SYS-SGB-(NT|2))\ ©\ 1994\ Nintendo\ (TC53[0-9]{4}[A-Z]{2})-[A-Z][0-9]{3}\ JAPAN\ ([0-9]{2})([0-9]{2})EAI$"#, - move |c| { - Ok(SgbRom { - rom_id: c[1].to_owned(), - manufacturer: Some(Manufacturer::Toshiba), - chip_type: (Some(c[3].to_owned())), - year: Some(year2(&c[4])?), - week: Some(week2(&c[5])?), + date_code: None, }) }, ) @@ -127,17 +55,19 @@ pub fn toshiba() -> &'static impl LabelParser { /// use gbhwdb_backend::parser::{self, LabelParser}; /// assert!(parser::sgb_rom::sharp_sgb().parse("SYS-SGB-2 © 1994 Nintendo LH532M0M 9432 E").is_ok()); /// ``` -pub fn sharp_sgb() -> &'static impl LabelParser { +pub fn sharp_sgb() -> &'static impl LabelParser { single_parser!( - SgbRom, + MaskRom, r#"^(SYS-SGB-NT|SYS-SGB-2)\ ©\ 1994\ Nintendo\ (LH[[:alnum:]]{4})[[:alnum:]]{2}\ ([0-9]{2})([0-9]{2})\ [A-Z]$"#, move |c| { - Ok(SgbRom { + Ok(MaskRom { rom_id: c[1].to_owned(), manufacturer: Some(Manufacturer::Sharp), chip_type: Some(c[2].to_owned()), - year: Some(year2(&c[3])?), - week: Some(week2(&c[4])?), + date_code: Some(PartDateCode::YearWeek { + year: year2(&c[3])?, + week: week2(&c[4])?, + }), }) }, ) @@ -149,54 +79,34 @@ pub fn sharp_sgb() -> &'static impl LabelParser { /// use gbhwdb_backend::parser::{self, LabelParser}; /// assert!(parser::sgb_rom::sharp_sgb2().parse("© 1998 Nintendo SYS-SGB2-10 LH5S4RY4 0003 D").is_ok()); /// ``` -pub fn sharp_sgb2() -> &'static impl LabelParser { +pub fn sharp_sgb2() -> &'static impl LabelParser { single_parser!( - SgbRom, + MaskRom, r#"^©\ 1998\ Nintendo\ (SYS-SGB2-10)\ (LH[[:alnum:]]{4})[[:alnum:]]{2}\ ([0-9]{2})([0-9]{2})\ [A-Z]$"#, move |c| { - Ok(SgbRom { + Ok(MaskRom { rom_id: c[1].to_owned(), manufacturer: Some(Manufacturer::Sharp), chip_type: Some(c[2].to_owned()), - year: Some(year2(&c[3])?), - week: Some(week2(&c[4])?), - }) - }, - ) -} - -/// OKI Semiconductor SGB/SGB2 ROM -/// -/// ``` -/// use gbhwdb_backend::parser::{self, LabelParser}; -/// assert!(parser::sgb_rom::oki().parse("SYS-SGB2-10 © 1998 Nintendo M534011E-05 8012354").is_ok()); -/// ``` -pub fn oki() -> &'static impl LabelParser { - single_parser!( - SgbRom, - r#"^(SYS-SGB-NT|SYS-SGB-2|SYS-SGB2-10)\ ©\ 1998\ Nintendo\ (M534011E)-[[:alnum:]]{2}\ ([0-9])([0-9]{2})[0-9]{3}[[:alnum:]]$"#, - move |c| { - Ok(SgbRom { - rom_id: c[1].to_owned(), - manufacturer: Some(Manufacturer::Oki), - chip_type: Some(c[2].to_owned()), - year: Some(year1(&c[3])?), - week: Some(week2(&c[4])?), + date_code: Some(PartDateCode::YearWeek { + year: year2(&c[3])?, + week: week2(&c[4])?, + }), }) }, ) } -pub fn sgb_rom() -> &'static impl LabelParser { +pub fn sgb_rom() -> &'static impl LabelParser { multi_parser!( - SgbRom, - toshiba(), + MaskRom, + &toshiba::TOSHIBA_SGB_ROM, sharp_sgb(), sharp_sgb2(), - oki(), - unknown(), + &oki::OKI_SGB_ROM, + &fujitsu::FUJITSU_SGB_ROM, unknown2(), unknown3(), - unknown4(), + &nec::NEC_SGB_ROM, ) } diff --git a/backend/src/parser/toshiba.rs b/backend/src/parser/toshiba.rs index 38ae4b00f..c1df1389c 100644 --- a/backend/src/parser/toshiba.rs +++ b/backend/src/parser/toshiba.rs @@ -3,8 +3,13 @@ // SPDX-License-Identifier: MIT use nom::{ - branch::alt, bytes::streaming::tag, character::streaming::char, combinator::value, - error::ParseError, sequence::tuple, Parser, + branch::alt, + bytes::streaming::tag, + character::streaming::char, + combinator::{recognize, value}, + error::ParseError, + sequence::{terminated, tuple}, + Parser, }; use super::{ @@ -188,6 +193,34 @@ pub static TOSHIBA_TC55V200: NomParser = NomParser { }, }; +/// Toshiba SGB mask ROM +/// +/// ``` +/// use gbhwdb_backend::parser::{self, LabelParser}; +/// assert!(parser::toshiba::TOSHIBA_SGB_ROM.parse("SYS-SGB-2 © 1994 Nintendo TC532000BF-N807 JAPAN 9431EAI").is_ok()); +/// ``` +pub static TOSHIBA_SGB_ROM: NomParser = NomParser { + name: "Toshiba SGB ROM", + f: |input| { + tuple(( + terminated(tag("SYS-SGB-2"), tag(" © 1994 Nintendo")), + char(' '), + recognize(tag("TC532000B").and(char(Package::SOP32.code_char()))) + .and(char('-').and(uppers(1)).and(digits(3))), + tag(" JAPAN "), + year2_week2, + tag("EAI"), + )) + .map(|(rom_id, _, (kind, _), _, date_code, _)| MaskRom { + rom_id: String::from(rom_id), + chip_type: Some(String::from(kind)), + manufacturer: Some(Manufacturer::Toshiba), + date_code: Some(date_code), + }) + .parse(input) + }, +}; + #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum Package { SOP20, diff --git a/site/src/main.rs b/site/src/main.rs index e0f871b10..9ad97cd40 100644 --- a/site/src/main.rs +++ b/site/src/main.rs @@ -606,7 +606,7 @@ fn read_sgb_submissions() -> Result, Error> { &console.mainboard.u1, parser::gen1_soc::gen1_soc(), ); - let icd2 = map_part(year_hint, &console.mainboard.u2, parser::icd2::icd2()); + let icd2 = map_part(year_hint, &console.mainboard.u2, parser::icd2()); let work_ram = map_part( year_hint, &console.mainboard.u3, @@ -878,7 +878,7 @@ fn read_sgb2_submissions() -> Result, Error> { &console.mainboard.u1, parser::gen2_soc::gen2_soc(), ); - let icd2 = map_part(year_hint, &console.mainboard.u2, parser::icd2::icd2()); + let icd2 = map_part(year_hint, &console.mainboard.u2, parser::icd2()); let work_ram = map_part( year_hint, &console.mainboard.u3, @@ -1267,7 +1267,7 @@ fn read_gbs_submissions() -> Result, Error> { &console.mainboard.u3, parser::sram::sram_tsop_i_48(), ); - let u4 = map_part(year_hint, &console.mainboard.u4, parser::gbs_dol::gbs_dol()); + let u4 = map_part(year_hint, &console.mainboard.u4, parser::gbs_dol()); let u5 = map_part(year_hint, &console.mainboard.u5, parser::gbs_reg()); let u6 = map_part(year_hint, &console.mainboard.u6, parser::gbs_reg()); let crystal = map_part( diff --git a/site/src/process/part.rs b/site/src/process/part.rs index 1617520e6..8f2788e66 100644 --- a/site/src/process/part.rs +++ b/site/src/process/part.rs @@ -135,18 +135,6 @@ impl ParsedPart for parser::Coil { } } -impl ParsedPart for parser::SgbRom { - fn process(self, year_hint: Option, label: String) -> ProcessedPart { - ProcessedPart { - label: Some(label), - kind: self.chip_type, - manufacturer: self.manufacturer, - date_code: DateCode::loose_year_week(year_hint, self.year, self.week), - rom_id: Some(self.rom_id), - } - } -} - impl ParsedPart for parser::ChipYearWeek { fn process(self, year_hint: Option, label: String) -> ProcessedPart { ProcessedPart {