From ae7716814d2da7df36a0bc39d9db6760725986ae Mon Sep 17 00:00:00 2001 From: Joonas Javanainen Date: Fri, 6 Dec 2024 18:15:39 +0200 Subject: [PATCH] Use more nom parsers --- model/src/config/cartridge.rs | 84 +++---- model/src/parser.rs | 1 + model/src/parser/eeprom.rs | 8 +- model/src/parser/fujitsu.rs | 2 +- model/src/parser/macronix.rs | 14 +- model/src/parser/mask_rom.rs | 231 +++---------------- model/src/parser/nec.rs | 48 ++-- model/src/parser/oki.rs | 54 ++--- model/src/parser/samsung.rs | 136 +++++++++++ model/src/parser/sgb_rom.rs | 56 +---- model/src/parser/sharp.rs | 413 +++++++++++++++++++++++++++++++++- 11 files changed, 686 insertions(+), 361 deletions(-) create mode 100644 model/src/parser/samsung.rs diff --git a/model/src/config/cartridge.rs b/model/src/config/cartridge.rs index 874127fd..68f82cab 100644 --- a/model/src/config/cartridge.rs +++ b/model/src/config/cartridge.rs @@ -20,12 +20,12 @@ use crate::{ parser::{ accelerometer::accelerometer, crystal_32kihz::crystal_32kihz, - eeprom::eeprom, + eeprom::{eeprom_sop_8_3v3, eeprom_tssop_8_5v}, flash_tsop_i_32_3v3, flash_tsop_i_40_5v, fram_sop_28_3v3, hex_inverter, line_decoder, mapper, mask_rom::{ - agb_mask_rom_tsop_ii_44, mask_rom_glop_top_28, mask_rom_qfp_44, mask_rom_sop_32, - mask_rom_sop_44_5v, mask_rom_tsop_i_32, mask_rom_tsop_ii_44_5v, + agb_mask_rom_tsop_ii_44_3v3, mask_rom_glop_top_28_5v, mask_rom_qfp_44_5v, + mask_rom_sop_32_5v, mask_rom_sop_44_5v, mask_rom_tsop_i_32_5v, mask_rom_tsop_ii_44_5v, }, rtc_sop_20, rtc_sop_8, sram::{sram_sop_28_3v3, sram_sop_28_5v, sram_sop_32_5v, sram_tsop_i_28}, @@ -179,33 +179,33 @@ impl BoardConfig { match self { BoardConfig::AgbArc => match designator { // TSOP-II-44 ROM - D::U1 => part(PartRole::Rom, agb_mask_rom_tsop_ii_44()), + D::U1 => part(PartRole::Rom, agb_mask_rom_tsop_ii_44_3v3()), // SOP-28 FRAM D::U2 => part(PartRole::Ram, fram_sop_28_3v3()), _ => None, }, BoardConfig::AgbE01 => match designator { // TSOP-II-44 ROM - D::U1 => part(PartRole::Rom, agb_mask_rom_tsop_ii_44()), + D::U1 => part(PartRole::Rom, agb_mask_rom_tsop_ii_44_3v3()), _ => None, }, BoardConfig::AgbE02 => match designator { // TSOP-II-44 ROM - D::U1 => part(PartRole::Rom, agb_mask_rom_tsop_ii_44()), + D::U1 => part(PartRole::Rom, agb_mask_rom_tsop_ii_44_3v3()), // TSOP-I-32 Flash D::U2 => part(PartRole::Flash, flash_tsop_i_32_3v3()), _ => None, }, BoardConfig::AgbE03 => match designator { // TSOP-II-44 ROM - D::U1 => part(PartRole::Rom, agb_mask_rom_tsop_ii_44()), + D::U1 => part(PartRole::Rom, agb_mask_rom_tsop_ii_44_3v3()), // SOP-8 EEPROM - D::U2 => part(PartRole::Eeprom, eeprom()), + D::U2 => part(PartRole::Eeprom, eeprom_sop_8_3v3()), _ => None, }, BoardConfig::AgbE05 => match designator { // TSOP-II-44 ROM - D::U1 => part(PartRole::Rom, agb_mask_rom_tsop_ii_44()), + D::U1 => part(PartRole::Rom, agb_mask_rom_tsop_ii_44_3v3()), // TSOP-I-32 Flash D::U2 => part(PartRole::Flash, flash_tsop_i_32_3v3()), // SOP-8 RTC @@ -215,7 +215,7 @@ impl BoardConfig { }, BoardConfig::AgbE06 => match designator { // TSOP-II-44 ROM - D::U1 => part(PartRole::Rom, agb_mask_rom_tsop_ii_44()), + D::U1 => part(PartRole::Rom, agb_mask_rom_tsop_ii_44_3v3()), // SOP-28 RAM D::U2 => part(PartRole::Ram, sram_sop_28_3v3()), // SOP-8 BU9803F @@ -224,7 +224,7 @@ impl BoardConfig { }, BoardConfig::AgbE11 | BoardConfig::AgbY11 => match designator { // TSOP-II-44 ROM - D::U1 => part(PartRole::Rom, agb_mask_rom_tsop_ii_44()), + D::U1 => part(PartRole::Rom, agb_mask_rom_tsop_ii_44_3v3()), // SOP-28 FRAM D::U2 => part(PartRole::Ram, fram_sop_28_3v3()), _ => None, @@ -233,17 +233,17 @@ impl BoardConfig { // QFP-32 D::U1 => part(PartRole::Unknown, unknown_chip()), // TSOP-II-44 ROM - D::U2 => part(PartRole::Rom, agb_mask_rom_tsop_ii_44()), + D::U2 => part(PartRole::Rom, agb_mask_rom_tsop_ii_44_3v3()), // SOP-8 EEPROM - D::U3 => part(PartRole::Eeprom, eeprom()), + D::U3 => part(PartRole::Eeprom, eeprom_sop_8_3v3()), D::U4 => part(PartRole::Accelerometer, accelerometer()), _ => None, }, BoardConfig::AgbE18 => match designator { // TSOP-II-44 ROM - D::U1 => part(PartRole::Rom, agb_mask_rom_tsop_ii_44()), + D::U1 => part(PartRole::Rom, agb_mask_rom_tsop_ii_44_3v3()), // SOP-8 EEPROM - D::U2 => part(PartRole::Eeprom, eeprom()), + D::U2 => part(PartRole::Eeprom, eeprom_sop_8_3v3()), // SOP-8 RTC D::U3 => part(PartRole::Rtc, rtc_sop_8()), D::U4 => part(PartRole::Unknown, unknown_chip()), @@ -253,9 +253,9 @@ impl BoardConfig { }, BoardConfig::AgbE24 => match designator { // TSOP-II-44 ROM - D::U1 => part(PartRole::Rom, agb_mask_rom_tsop_ii_44()), + D::U1 => part(PartRole::Rom, agb_mask_rom_tsop_ii_44_3v3()), // SOP-8 EEPROM - D::U2 => part(PartRole::Eeprom, eeprom()), + D::U2 => part(PartRole::Eeprom, eeprom_sop_8_3v3()), _ => None, }, BoardConfig::Tama => match designator { @@ -274,14 +274,14 @@ impl BoardConfig { }, BoardConfig::Aaac => match designator { // glop top ROM, 28 pads - D::U1 => part(PartRole::Rom, mask_rom_glop_top_28()), + D::U1 => part(PartRole::Rom, mask_rom_glop_top_28_5v()), _ => None, }, BoardConfig::CgbA32 => match designator { // QFP-64 MBC6 D::U1 => part(PartRole::Mapper, mapper::mbc6_qfp64()), // SOP-32 ROM - D::U2 => part(PartRole::Rom, mask_rom_sop_32()), + D::U2 => part(PartRole::Rom, mask_rom_sop_32_5v()), // TSOP-I-40 Flash D::U3 => part(PartRole::Flash, flash_tsop_i_40_5v()), // SOP-28 RAM @@ -292,7 +292,7 @@ impl BoardConfig { }, BoardConfig::DmgA02 => match designator { // SOP-32 ROM - D::U1 => part(PartRole::Rom, mask_rom_sop_32()), + D::U1 => part(PartRole::Rom, mask_rom_sop_32_5v()), // QFP-32 MBC5 D::U2 => part(PartRole::Mapper, mapper::mbc5_qfp32()), // SOP-28 RAM @@ -314,7 +314,7 @@ impl BoardConfig { }, BoardConfig::DmgA04 => match designator { // TSOP-I-32 ROM - D::U1 => part(PartRole::Rom, mask_rom_tsop_i_32()), + D::U1 => part(PartRole::Rom, mask_rom_tsop_i_32_5v()), // QFP-32 MBC5 D::U2 => part(PartRole::Mapper, mapper::mbc5_qfp32()), // SOP-28 RAM @@ -326,7 +326,7 @@ impl BoardConfig { }, BoardConfig::DmgA06 => match designator { // SOP-32 ROM - D::U1 => part(PartRole::Rom, mask_rom_sop_32()), + D::U1 => part(PartRole::Rom, mask_rom_sop_32_5v()), // QFP-32 MBC5 D::U2 => part(PartRole::Mapper, mapper::mbc5_qfp32()), // SOP-28 RAM @@ -337,7 +337,7 @@ impl BoardConfig { }, BoardConfig::DmgA07 => match designator { // SOP-32 ROM - D::U1 => part(PartRole::Rom, mask_rom_sop_32()), + D::U1 => part(PartRole::Rom, mask_rom_sop_32_5v()), // QFP-32 MBC5 D::U2 => part(PartRole::Mapper, mapper::mbc5_qfp32()), _ => None, @@ -389,7 +389,7 @@ impl BoardConfig { }, BoardConfig::DmgA16 => match designator { // SOP-32 ROM - D::U1 => part(PartRole::Rom, mask_rom_sop_32()), + D::U1 => part(PartRole::Rom, mask_rom_sop_32_5v()), // QFP-32 MBC5 D::U2 => part(PartRole::Mapper, mapper::mbc5_qfp32()), // SOP-32 RAM @@ -409,9 +409,9 @@ impl BoardConfig { // QFP-56 MBC7 D::U1 => part(PartRole::Mapper, mapper::mbc7_qfp56()), // SOP-32 ROM - D::U2 => part(PartRole::Rom, mask_rom_sop_32()), + D::U2 => part(PartRole::Rom, mask_rom_sop_32_5v()), // TSSOP-8 EEPROM - D::U3 => part(PartRole::Eeprom, eeprom()), + D::U3 => part(PartRole::Eeprom, eeprom_tssop_8_5v()), // QC-14 accelerometer D::U4 => part(PartRole::Accelerometer, accelerometer()), _ => None, @@ -422,19 +422,19 @@ impl BoardConfig { // TSOP-II-44 ROM D::U2 => part(PartRole::Rom, mask_rom_tsop_ii_44_5v()), // TSSOP-8 EEPROM - D::U3 => part(PartRole::Eeprom, eeprom()), + D::U3 => part(PartRole::Eeprom, eeprom_tssop_8_5v()), // QC-14 accelerometer D::U4 => part(PartRole::Accelerometer, accelerometer()), _ => None, }, BoardConfig::DmgAaa => match designator { - // QFP-44 ROM - D::U1 => part(PartRole::Rom, mask_rom_qfp_44()), + // QFP-44 ROM, LH53259-compatible pinout + D::U1 => part(PartRole::Rom, mask_rom_qfp_44_5v()), _ => None, }, BoardConfig::DmgBba | BoardConfig::DmgBca => match designator { // QFP-44 ROM - D::U1 => part(PartRole::Rom, mask_rom_qfp_44()), + D::U1 => part(PartRole::Rom, mask_rom_qfp_44_5v()), // SOP-24 MBC1 D::U2 => part(PartRole::Mapper, mapper::mbc1_sop24()), _ => None, @@ -442,7 +442,7 @@ impl BoardConfig { BoardConfig::DmgBean | BoardConfig::DmgBfan | BoardConfig::DmgMBfan => match designator { // SOP-32 ROM - D::U1 => part(PartRole::Rom, mask_rom_sop_32()), + D::U1 => part(PartRole::Rom, mask_rom_sop_32_5v()), // SOP-24 MBC1 D::U2 => part(PartRole::Mapper, mapper::mbc1_sop24()), _ => None, @@ -450,7 +450,7 @@ impl BoardConfig { BoardConfig::DmgDecn | BoardConfig::DmgDedn | BoardConfig::DmgMcDfcn => { match designator { // SOP-32 ROM - D::U1 => part(PartRole::Rom, mask_rom_sop_32()), + D::U1 => part(PartRole::Rom, mask_rom_sop_32_5v()), // SOP-24 MBC1 D::U2 => part(PartRole::Mapper, mapper::mbc1_sop24()), // SOP-28 RAM @@ -473,7 +473,7 @@ impl BoardConfig { }, BoardConfig::DmgGdan => match designator { // SOP-32 ROM - D::U1 => part(PartRole::Rom, mask_rom_sop_32()), + D::U1 => part(PartRole::Rom, mask_rom_sop_32_5v()), // SOP-28 MBC2 D::U2 => part(PartRole::Mapper, mapper::mbc2_sop28()), // SOP-8 26A @@ -482,7 +482,7 @@ impl BoardConfig { }, BoardConfig::DmgKecn => match designator { // SOP-32 ROM - D::U1 => part(PartRole::Rom, mask_rom_sop_32()), + D::U1 => part(PartRole::Rom, mask_rom_sop_32_5v()), // QFP-32 MBC3 D::U2 => part(PartRole::Mapper, mapper::mbc3_qfp32()), // SOP-28 RAM @@ -494,7 +494,7 @@ impl BoardConfig { }, BoardConfig::DmgKfcn | BoardConfig::DmgKfdn => match designator { // SOP-32 ROM - D::U1 => part(PartRole::Rom, mask_rom_sop_32()), + D::U1 => part(PartRole::Rom, mask_rom_sop_32_5v()), // QFP-32 MBC3 D::U2 => part(PartRole::Mapper, mapper::mbc3_qfp32()), // SOP-28 RAM @@ -518,7 +518,7 @@ impl BoardConfig { }, BoardConfig::DmgLfdn => match designator { // SOP-32 ROM - D::U1 => part(PartRole::Rom, mask_rom_sop_32()), + D::U1 => part(PartRole::Rom, mask_rom_sop_32_5v()), // QFP-32 MBC3 D::U2 => part(PartRole::Mapper, mapper::mbc3_qfp32()), // SOP-28 RAM @@ -529,7 +529,7 @@ impl BoardConfig { }, BoardConfig::DmgMcSfcn => match designator { // SOP-32 ROM - D::U1 => part(PartRole::Rom, mask_rom_sop_32()), + D::U1 => part(PartRole::Rom, mask_rom_sop_32_5v()), // QFP-32 MMM01 D::U2 => part(PartRole::Mapper, mapper::mmm01_qfp32()), // SOP-28 RAM @@ -552,7 +552,7 @@ impl BoardConfig { }, BoardConfig::DmgTedn => match designator { // SOP-32 ROM - D::U1 => part(PartRole::Rom, mask_rom_sop_32()), + D::U1 => part(PartRole::Rom, mask_rom_sop_32_5v()), // QFP-32 HuC-1 D::U2 => part(PartRole::Mapper, mapper::huc1_qfp32()), // SOP-28 RAM @@ -564,7 +564,7 @@ impl BoardConfig { }, BoardConfig::DmgTfdn => match designator { // SOP-32 ROM - D::U1 => part(PartRole::Rom, mask_rom_sop_32()), + D::U1 => part(PartRole::Rom, mask_rom_sop_32_5v()), // QFP-32 HuC-1 D::U2 => part(PartRole::Mapper, mapper::huc1_qfp32()), // SOP-28 RAM @@ -576,7 +576,7 @@ impl BoardConfig { }, BoardConfig::DmgUedt => match designator { // TSOP-I-32 ROM - D::U1 => part(PartRole::Rom, mask_rom_tsop_i_32()), + D::U1 => part(PartRole::Rom, mask_rom_tsop_i_32_5v()), // QFP-48 HuC-3 D::U2 => part(PartRole::Mapper, mapper::huc3_qfp48()), // TSOP-I-28 RAM @@ -590,7 +590,7 @@ impl BoardConfig { }, BoardConfig::DmgUfdt => match designator { // TSOP-I-32 ROM - D::U1 => part(PartRole::Rom, mask_rom_tsop_i_32()), + D::U1 => part(PartRole::Rom, mask_rom_tsop_i_32_5v()), // QFP-48 HuC-3 D::U2 => part(PartRole::Mapper, mapper::huc3_qfp48()), // TSOP-I-28 RAM @@ -618,7 +618,7 @@ impl BoardConfig { }, BoardConfig::DmgZ02 => match designator { // SOP-32 ROM - D::U1 => part(PartRole::Rom, mask_rom_sop_32()), + D::U1 => part(PartRole::Rom, mask_rom_sop_32_5v()), // QFP-32 MBC5 D::U2 => part(PartRole::Mapper, mapper::mbc5_qfp32()), // SOP-28 RAM diff --git a/model/src/parser.rs b/model/src/parser.rs index bee741f4..4534645d 100644 --- a/model/src/parser.rs +++ b/model/src/parser.rs @@ -67,6 +67,7 @@ pub mod oki; pub mod oxy_u4; pub mod oxy_u5; pub mod rohm; +pub mod samsung; pub mod sanyo; pub mod seiko; pub mod sgb_rom; diff --git a/model/src/parser/eeprom.rs b/model/src/parser/eeprom.rs index dcf00946..0c0c349c 100644 --- a/model/src/parser/eeprom.rs +++ b/model/src/parser/eeprom.rs @@ -54,6 +54,10 @@ pub static LC56: NomParser = NomParser { }, }; -pub fn eeprom() -> &'static impl LabelParser { - multi_parser!(Eeprom, &LCS5, &LC56, &rohm::ROHM_9853, &rohm::ROHM_9854) +pub fn eeprom_sop_8_3v3() -> &'static impl LabelParser { + multi_parser!(Eeprom, &rohm::ROHM_9853, &rohm::ROHM_9854) +} + +pub fn eeprom_tssop_8_5v() -> &'static impl LabelParser { + multi_parser!(Eeprom, &LCS5, &LC56) } diff --git a/model/src/parser/fujitsu.rs b/model/src/parser/fujitsu.rs index 4bdc628b..5f6f298b 100644 --- a/model/src/parser/fujitsu.rs +++ b/model/src/parser/fujitsu.rs @@ -89,7 +89,7 @@ pub static FUJITSU_MASK_ROM: NomParser = NomParser { tag("JAPAN "), alt((dmg_rom_code(), cgb_rom_code())), char(' '), - uppers(1).and(digits(1)), + alt((tag("D1"), tag("E1"))), // D1 = 2Mbit, E1 = 4Mbit ? char(' '), digits(1).and(uppers(1)).and(alnum_uppers(1)), char(' '), diff --git a/model/src/parser/macronix.rs b/model/src/parser/macronix.rs index d4c3ad4d..f144bccd 100644 --- a/model/src/parser/macronix.rs +++ b/model/src/parser/macronix.rs @@ -282,7 +282,7 @@ fn gb_mx23c<'a, E: ParseError<&'a str>>( ) } -/// Macronix MX23C4002 (SOP-32, 4.5-5.5V) +/// Macronix MX23C4002 (SOP-32, 4.5-5.5V, 4 Mibit / 512 KiB) /// /// ``` /// use gbhwdb_model::parser::{self, LabelParser}; @@ -300,7 +300,7 @@ pub static MACRONIX_MX23C4002: NomParser = NomParser { }, }; -/// Macronix MX23C8003 (SOP-32, 4.5-5.5V) +/// Macronix MX23C8003 (SOP-32, 4.5-5.5V, 8 Mibit / 1 MiB) /// /// ``` /// use gbhwdb_model::parser::{self, LabelParser}; @@ -311,7 +311,7 @@ pub static MACRONIX_MX23C8003: NomParser = NomParser { f: |input| gb_mx23c("MX23C8003-20", "49", "F1").parse(input), }; -/// Macronix MX23C8005 (SOP-32, 4.5-5.5V) +/// Macronix MX23C8005 (SOP-32, 4.5-5.5V, 8 Mibit / 1 MiB) /// /// ``` /// use gbhwdb_model::parser::{self, LabelParser}; @@ -322,7 +322,7 @@ pub static MACRONIX_MX23C8005: NomParser = NomParser { f: |input| gb_mx23c("MX23C8005-12", "49", "F1").parse(input), }; -/// Macronix MX23C8006 (TSOP-I-32, 4.5-5.5V) +/// Macronix MX23C8006 (TSOP-I-32, 4.5-5.5V, 8 Mibit / 1 MiB) /// /// ``` /// use gbhwdb_model::parser::{self, LabelParser}; @@ -333,7 +333,7 @@ pub static MACRONIX_MX23C8006: NomParser = NomParser { f: |input| gb_mx23c("MX23C8006-12", "49", "F").parse(input), }; -/// Macronix MX23C1603 (TSOP-II-44, 4.5-5.5V) +/// Macronix MX23C1603 (TSOP-II-44, 4.5-5.5V, 16 Mibit / 2 MiB) /// /// ``` /// use gbhwdb_model::parser::{self, LabelParser}; @@ -352,7 +352,7 @@ pub static MACRONIX_MX23C1603: NomParser = NomParser { }, }; -/// Macronix MX23C1605 (SOP-44, 4.5-5.5V) +/// Macronix MX23C1605 (SOP-44, 4.5-5.5V, 16 Mibit / 2 MiB) /// /// ``` /// use gbhwdb_model::parser::{self, LabelParser}; @@ -363,7 +363,7 @@ pub static MACRONIX_MX23C1605: NomParser = NomParser { f: |input| gb_mx23c("MX23C1605-12A", "19", "G1").parse(input), }; -/// Macronix MX23C3203 (TSOP-II-44, 4.5-5.5V) +/// Macronix MX23C3203 (TSOP-II-44, 4.5-5.5V, 32 Mibit / 4 MiB) /// /// ``` /// use gbhwdb_model::parser::{self, LabelParser}; diff --git a/model/src/parser/mask_rom.rs b/model/src/parser/mask_rom.rs index 0c77eef4..1a95990c 100644 --- a/model/src/parser/mask_rom.rs +++ b/model/src/parser/mask_rom.rs @@ -2,10 +2,10 @@ // // SPDX-License-Identifier: MIT -use super::{week2, year2, LabelParser, Manufacturer, ParsedData, PartDateCode}; +use super::{LabelParser, Manufacturer, ParsedData, PartDateCode}; use crate::{ macros::{multi_parser, single_parser}, - parser::{fujitsu::FUJITSU_MASK_ROM, macronix, nec, oki, toshiba}, + parser::{fujitsu, macronix, nec, oki, samsung, sharp, toshiba}, }; #[derive(Clone, Debug, Eq, PartialEq)] @@ -18,148 +18,6 @@ pub struct MaskRom { impl ParsedData for MaskRom {} -/// Sharp ROM chip (1990+) -/// -/// ``` -/// use gbhwdb_model::parser::{self, LabelParser}; -/// assert!(parser::mask_rom::sharp().parse("DMG-WJA-0 S LH534M05 JAPAN E1 9606 D").is_ok()); -/// assert!(parser::mask_rom::sharp().parse("DMG-AP2J-0 S LH534MVD JAPAN E1 9639 D").is_ok()); -/// assert!(parser::mask_rom::sharp().parse("DMG-HFAJ-0 S LHMN4MTI JAPAN E 9838 E").is_ok()); -/// ``` -pub fn sharp() -> &'static impl LabelParser { - single_parser!( - MaskRom, - r#"^((DMG|CGB)-[[:alnum:]]{3,4}-[0-9])\ S\ (LH[[:alnum:]]{4})[[:alnum:]]{2} \ JAPAN\ [A-Z][0-9]?\ ([0-9]{2})([0-9]{2})\ [A-Z]$"#, - move |c| { - Ok(MaskRom { - rom_id: c[1].to_owned(), - manufacturer: Some(Manufacturer::Sharp), - chip_type: Some(map_sharp_mask_rom(&c[3]).unwrap_or(&c[3]).to_owned()), - date_code: Some(PartDateCode::YearWeek { - year: year2(&c[4])?, - week: week2(&c[5])?, - }), - }) - }, - ) -} - -/// Old sharp ROM chip with no chip type (1989 - 1991) -/// -/// ``` -/// use gbhwdb_model::parser::{self, LabelParser}; -/// assert!(parser::mask_rom::sharp2().parse("DMG-TRA-1 SHARP JAPAN A0 9019 D").is_ok()); -/// ``` -pub fn sharp2() -> &'static impl LabelParser { - single_parser!( - MaskRom, - r#"^(DMG-[[:alnum:]]{3}-[0-9])\ SHARP\ JAPAN\ [A-Z][0-9]?\ ([0-9]{2})([0-9]{2})\ [A-Z]$"#, - move |c| { - Ok(MaskRom { - rom_id: c[1].to_owned(), - manufacturer: Some(Manufacturer::Sharp), - chip_type: None, - date_code: Some(PartDateCode::YearWeek { - year: year2(&c[2])?, - week: week2(&c[3])?, - }), - }) - }, - ) -} - -/// Very old Sharp mask ROM chip (1989 and older) -/// -/// ``` -/// use gbhwdb_model::parser::{self, LabelParser}; -/// assert!(parser::mask_rom::sharp3().parse("DMG-AWA-0 SHARP JAPAN 8909 D A").is_ok()); -/// ``` -pub fn sharp3() -> &'static impl LabelParser { - single_parser!( - MaskRom, - r#"^(DMG-[[:alnum:]]{3}-[0-9])\ SHARP\ JAPAN\ ([0-9]{2})([0-9]{2})\ [A-Z]\ [A-Z]$"#, - move |c| { - Ok(MaskRom { - rom_id: c[1].to_owned(), - manufacturer: Some(Manufacturer::Sharp), - chip_type: None, - date_code: Some(PartDateCode::YearWeek { - year: year2(&c[2])?, - week: week2(&c[3])?, - }), - }) - }, - ) -} - -/// Glop top mask ROM. -/// -/// Probably manufactured by Sharp (?) -/// -/// ``` -/// use gbhwdb_model::parser::{self, LabelParser}; -/// assert!(parser::mask_rom::sharp_glop_top_28().parse("LR0G150 DMG-TRA-1 97141").is_ok()); -/// ``` -pub fn sharp_glop_top_28() -> &'static impl LabelParser { - single_parser!( - MaskRom, - r#"^(LR0G150)\ (DMG-[[:alnum:]]{3}-[0-9])\ ([0-9]{2})([0-9]{2})[0-9]$"#, - move |c| { - Ok(MaskRom { - rom_id: c[2].to_owned(), - manufacturer: None, - chip_type: Some(c[1].to_owned()), - date_code: Some(PartDateCode::YearWeek { - year: year2(&c[3])?, - week: week2(&c[4])?, - }), - }) - }, - ) -} - -/// Samsung mask ROM -/// -/// ``` -/// use gbhwdb_model::parser::{self, LabelParser}; -/// assert!(parser::mask_rom::samsung().parse("SEC KM23C16120DT CGB-BHMJ-0 G2 K3N5C317GD").is_ok()); -/// ``` -pub fn samsung() -> &'static impl LabelParser { - single_parser!( - MaskRom, - r#"^SEC\ (KM23C[0-9]{4,5}[A-Z]{1,2})\ ((DMG|CGB)-[[:alnum:]]{3,4}-[0-9])\ [A-Z][0-9]\ [[:alnum:]]{10}$"#, - move |c| { - Ok(MaskRom { - rom_id: c[2].to_owned(), - manufacturer: Some(Manufacturer::Samsung), - chip_type: (Some(c[1].to_owned())), - date_code: None, - }) - }, - ) -} - -/// Old samsung mask ROM -/// -/// ``` -/// use gbhwdb_model::parser::{self, LabelParser}; -/// assert!(parser::mask_rom::samsung2().parse("SEC KM23C8000DG DMG-AAUJ-1 F1 KFX331U").is_ok()); -/// ``` -pub fn samsung2() -> &'static impl LabelParser { - single_parser!( - MaskRom, - r#"^SEC\ (KM23C[0-9]{4,5}[A-Z]{1,2})\ ((DMG|CGB)-[[:alnum:]]{3,4}-[0-9])\ [A-Z][0-9]\ KF[[:alnum:]]{4}[A-Z]$"#, - move |c| { - Ok(MaskRom { - rom_id: c[2].to_owned(), - manufacturer: Some(Manufacturer::Samsung), - chip_type: (Some(c[1].to_owned())), - date_code: None, - }) - }, - ) -} - /// Magnachip AC23V Mask ROM /// /// ``` @@ -204,43 +62,7 @@ pub fn hynix_ac23v() -> &'static impl LabelParser { ) } -fn map_sharp_mask_rom(code: &str) -> Option<&'static str> { - match code { - "LH5359" => Some("LH53259"), // Sharp Memory Data Book 1992 - "LH5317" => Some("LH53517"), // Unknown mask ROM listing scan - "LH531H" => Some("LH530800A"), // Sharp Memory Data Book 1992 - // reasonable guesses - "LH5308" => Some("LH530800"), // unknown 1Mb JEDEC, compatible with LH530800A - "LH5314" => Some("LH53514"), // unknown 512Kb JEDEC, compatible with LH53517 - "LH5321" => Some("LH532100"), // unknown 2Mb JEDEC - // unknown 2Mb JEDEC - // maybe: LH532100 series / LH532300 / LH532700 series - "LH532D" => None, - "LH532M" => None, - "LH532W" => None, - "LHMN2E" => None, - // Unknown 4Mb JEDEC - // maybe: LH534100 series / LH534300 series / LH534R00 - "LH534M" => None, - "LH5S4M" => None, - "LHMN4M" => None, - // Unknown 8Mb JEDEC - // maybe: LH538300 series / LH538400 series / LH538700 / LH538R00 series - "LH538M" => None, - "LH538W" => None, - "LH5S8M" => None, - "LHMN8J" => None, - "LHMN8M" => None, - // Unknown 16 Mb - // maybe: LH5316400 / LH5316500 series / LH5316P00 series - "LH537M" => None, - // Unknown 32 Mb - "LHMN5M" => None, - _ => None, - } -} - -pub fn agb_mask_rom_tsop_ii_44() -> &'static impl LabelParser { +pub fn agb_mask_rom_tsop_ii_44_3v3() -> &'static impl LabelParser { multi_parser!( MaskRom, magnachip_ac23v(), @@ -264,16 +86,21 @@ pub fn agb_mask_rom_tsop_ii_44() -> &'static impl LabelParser { ) } -pub fn mask_rom_glop_top_28() -> &'static impl LabelParser { - sharp_glop_top_28() +pub fn mask_rom_glop_top_28_5v() -> &'static impl LabelParser { + &sharp::SHARP_MASK_ROM_GLOP_TOP_28_256_KIBIT } -pub fn mask_rom_sop_32() -> &'static impl LabelParser { +pub fn mask_rom_sop_32_5v() -> &'static impl LabelParser { multi_parser!( MaskRom, - sharp(), - sharp2(), - sharp3(), + &sharp::SHARP_MASK_ROM_SOP_32_1_MIBIT, + &sharp::SHARP_LH53514Z, + &sharp::SHARP_LH53517Z, + &sharp::SHARP_LH530800N, + &sharp::SHARP_LH532100N, + &sharp::SHARP_LH532XXXN, + &sharp::SHARP_LH534XXXN, + &sharp::SHARP_LH538XXXN, ¯onix::MACRONIX_MX23C4002, ¯onix::MACRONIX_MX23C8003, ¯onix::MACRONIX_MX23C8005, @@ -289,9 +116,9 @@ pub fn mask_rom_sop_32() -> &'static impl LabelParser { &toshiba::TOSHIBA_TC531001, &toshiba::TOSHIBA_TC532000, &toshiba::TOSHIBA_TC534000, - samsung(), - samsung2(), - &FUJITSU_MASK_ROM, + &samsung::SAMSUNG_KM23C4000, + &samsung::SAMSUNG_KM23C8000, + &fujitsu::FUJITSU_MASK_ROM, ) } @@ -299,39 +126,33 @@ pub fn mask_rom_sop_44_5v() -> &'static impl LabelParser { multi_parser!(MaskRom, ¯onix::MACRONIX_MX23C1605,) } -pub fn mask_rom_tsop_i_32() -> &'static impl LabelParser { +pub fn mask_rom_tsop_i_32_5v() -> &'static impl LabelParser { multi_parser!( MaskRom, - sharp(), + &sharp::SHARP_LH534XXXS, + &sharp::SHARP_LH538XXXS, ¯onix::MACRONIX_MX23C8006, - samsung(), - samsung2(), ) } pub fn mask_rom_tsop_ii_44_5v() -> &'static impl LabelParser { multi_parser!( MaskRom, - sharp(), - sharp2(), - sharp3(), + &sharp::SHARP_LH5316XXX, + &sharp::SHARP_LH5332XXX, ¯onix::MACRONIX_MX23C1603, ¯onix::MACRONIX_MX23C3203, &oki::OKI_MR531614, &nec::NEC_UPD23C16019W, - samsung(), - samsung2(), + &samsung::SAMSUNG_KM23C16120, ) } -pub fn mask_rom_qfp_44() -> &'static impl LabelParser { +pub fn mask_rom_qfp_44_5v() -> &'static impl LabelParser { multi_parser!( MaskRom, - sharp(), - sharp2(), - sharp3(), - samsung(), - samsung2(), + &sharp::SHARP_LH53259M, + &sharp::SHARP_LH53515M, &oki::OKI_OLD_MASK_ROM, ) } diff --git a/model/src/parser/nec.rs b/model/src/parser/nec.rs index 2b2d283a..c10b9ac5 100644 --- a/model/src/parser/nec.rs +++ b/model/src/parser/nec.rs @@ -94,11 +94,12 @@ pub static NEC_UPD442012L_X: NomParser = NomParser { fn upd23c<'a, E: ParseError<&'a str>>( chip_type: &'static str, package: Package, + unknown: &'static str, ) -> impl Parser<&'a str, MaskRom, E> { tuple(( alt((dmg_rom_code(), cgb_rom_code())), char(' '), - uppers(1).and(digits(1)), + tag(unknown), char(' '), tuple(( value("μPD23C", tag("N-")), @@ -122,12 +123,13 @@ fn upd23c<'a, E: ParseError<&'a str>>( fn upd23c_old<'a, E: ParseError<&'a str>>( chip_type: &'static str, package: Package, + unknown: &'static str, ) -> impl Parser<&'a str, MaskRom, E> { tuple(( tag("NEC JAPAN "), alt((dmg_rom_code(), cgb_rom_code())), char(' '), - uppers(1).and(digits(1)), + tag(unknown), char(' '), tuple(( value("μPD23C", tag("UPD23C")), @@ -152,13 +154,13 @@ fn upd23c_licensed<'a, E: ParseError<&'a str>>( chip_type: &'static str, package: Package, (manufacturer_text, manufacturer): (&'static str, Manufacturer), - long: bool, + unknown: &'static str, ) -> impl Parser<&'a str, MaskRom, E> { tuple(( tag(manufacturer_text), char(' '), alt((dmg_rom_code(), cgb_rom_code())), - cond(long, tuple((char(' '), uppers(1).and(digits(1))))), + cond(!unknown.is_empty(), tuple((char(' '), tag(unknown)))), char(' '), tuple(( value("μPD23C", tag("23C")), @@ -191,10 +193,10 @@ pub static NEC_UPD23C1001E: NomParser = NomParser { f: |input| { let package = Package::Sop32; alt(( - upd23c_old("1001E", package), - upd23c("1001E", package), - upd23c("1001EA", package), - upd23c("1001EU", package), + upd23c_old("1001E", package, "C1"), + upd23c("1001E", package, "C1"), + upd23c("1001EA", package, "C1"), + upd23c("1001EU", package, "C1"), )) .parse(input) }, @@ -210,7 +212,11 @@ pub static NEC_UPD23C2001E: NomParser = NomParser { name: "NEC μPD23C2001E", f: |input| { let package = Package::Sop32; - alt((upd23c("2001E", package), upd23c("2001EU", package))).parse(input) + alt(( + upd23c("2001E", package, "D1"), + upd23c("2001EU", package, "D1"), + )) + .parse(input) }, }; @@ -226,9 +232,9 @@ pub static NEC_UPD23C4001E: NomParser = NomParser { f: |input| { let package = Package::Sop32; alt(( - upd23c("4001EA", package), - upd23c("4001EJ", package), - upd23c("4001EU", package), + upd23c("4001EA", package, "E1"), + upd23c("4001EJ", package, "E1"), + upd23c("4001EU", package, "E1"), )) .parse(input) }, @@ -242,7 +248,7 @@ pub static NEC_UPD23C4001E: NomParser = NomParser { /// ``` pub static NEC_UPD23C8001E: NomParser = NomParser { name: "NEC μPD23C8001E", - f: |input| upd23c("8001EJ", Package::Sop32).parse(input), + f: |input| upd23c("8001EJ", Package::Sop32, "F1").parse(input), }; /// NEC μPD23C16019W (TSOP-II-44, 5V) @@ -253,7 +259,7 @@ pub static NEC_UPD23C8001E: NomParser = NomParser { /// ``` pub static NEC_UPD23C16019W: NomParser = NomParser { name: "NEC μPD23C16019W", - f: |input| upd23c("16019W", Package::TsopIi44).parse(input), + f: |input| upd23c("16019W", Package::TsopIi44, "G2").parse(input), }; /// AT&T μPD23C1001E (SOP-32, 5V) @@ -271,7 +277,7 @@ pub static AT_T_UPD23C1001E: NomParser = NomParser { "1001EA", Package::Sop32, ("Ⓜ AT&T JAPAN", Manufacturer::AtT), - true, + "C1", ) .parse(input) }, @@ -291,8 +297,8 @@ pub static SMSC_UPD23C1001E: NomParser = NomParser { let package = Package::Sop32; let manufacturer = ("STANDARD MICRO", Manufacturer::Smsc); alt(( - upd23c_licensed("1001E", package, manufacturer, true), - upd23c_licensed("1001EA", package, manufacturer, true), + upd23c_licensed("1001E", package, manufacturer, "C1"), + upd23c_licensed("1001EA", package, manufacturer, "C1"), )) .parse(input) }, @@ -309,13 +315,7 @@ pub static SMSC_UPD23C1001E: NomParser = NomParser { pub static MANI_UPD23C4001E: NomParser = NomParser { name: "MANI μPD23C4001E", f: |input| { - upd23c_licensed( - "4001EA", - Package::Sop32, - ("MANI", Manufacturer::Mani), - false, - ) - .parse(input) + upd23c_licensed("4001EA", Package::Sop32, ("MANI", Manufacturer::Mani), "").parse(input) }, }; diff --git a/model/src/parser/oki.rs b/model/src/parser/oki.rs index 6e8bf333..c37dafcb 100644 --- a/model/src/parser/oki.rs +++ b/model/src/parser/oki.rs @@ -10,7 +10,7 @@ use nom::{ use super::{ for_nom::{ agb_rom_code, alnum_uppers, cgb_rom_code, digits, dmg_rom_code, satisfy_m_n_complete, - uppers, year1_week2, + year1_week2, }, MaskRom, }; @@ -49,11 +49,12 @@ pub static OKI_OLD_MASK_ROM: NomParser = NomParser { fn gb<'a, E: ParseError<&'a str>>( prefix: &'static str, chip_type: &'static str, + unknown: &'static str, ) -> impl Parser<&'a str, MaskRom, E> { tuple(( alt((dmg_rom_code(), cgb_rom_code())), char(' '), - uppers(1).and(digits(1)), + tag(unknown), char(' '), tag(chip_type).and(char('-').and(alnum_uppers(2))), char(' '), @@ -69,7 +70,7 @@ fn gb<'a, E: ParseError<&'a str>>( ) } -/// OKI MSM534011 (SOP-32, 5V) +/// OKI MSM534011 (SOP-32, 5V, 4 Mibit / 512 KiB) /// /// ``` /// use gbhwdb_model::parser::{self, LabelParser}; @@ -77,10 +78,10 @@ fn gb<'a, E: ParseError<&'a str>>( /// ``` pub static OKI_MSM534011: NomParser = NomParser { name: "OKI MSM534011", - f: |input| gb("MS", "M534011E").parse(input), + f: |input| gb("MS", "M534011E", "E1").parse(input), }; -/// OKI MSM538011 (SOP-32, 5V) +/// OKI MSM538011 (SOP-32, 5V, 8 Mibit / 1 MiB) /// /// ``` /// use gbhwdb_model::parser::{self, LabelParser}; @@ -89,10 +90,10 @@ pub static OKI_MSM534011: NomParser = NomParser { /// ``` pub static OKI_MSM538011: NomParser = NomParser { name: "OKI MSM538011", - f: |input| gb("MS", "M538011E").parse(input), + f: |input| gb("MS", "M538011E", "F1").parse(input), }; -/// OKI MR531614 (TSOP-II-44, 5V) +/// OKI MR531614 (TSOP-II-44, 5V, 16 Mibit / 2 MiB) /// /// ``` /// use gbhwdb_model::parser::{self, LabelParser}; @@ -100,17 +101,18 @@ pub static OKI_MSM538011: NomParser = NomParser { /// ``` pub static OKI_MR531614: NomParser = NomParser { name: "OKI MR531614", - f: |input| gb("M", "R531614G").parse(input), + f: |input| gb("M", "R531614G", "G2").parse(input), }; fn gba<'a, E: ParseError<&'a str>>( prefix: &'static str, chip_type: &'static str, + unknown: &'static str, ) -> impl Parser<&'a str, MaskRom, E> { tuple(( agb_rom_code(), char(' '), - uppers(1).and(digits(1)), + tag(unknown), char(' '), tag(chip_type).and(char('-').and(char('0').and(alnum_uppers(2)))), char(' '), @@ -129,7 +131,7 @@ fn gba<'a, E: ParseError<&'a str>>( ) } -/// OKI MR26V3210 (TSOP-II-44, 3.3V, 4 MiB) +/// OKI MR26V3210 (TSOP-II-44, 3.3V, 32 Mibit / 4 MiB) /// /// ``` /// use gbhwdb_model::parser::{self, LabelParser}; @@ -137,10 +139,10 @@ fn gba<'a, E: ParseError<&'a str>>( /// ``` pub static OKI_MR26V3210: NomParser = NomParser { name: "OKI MR26V3210", - f: |input| gba("M", "R26V3210F").parse(input), + f: |input| gba("M", "R26V3210F", "H2").parse(input), }; -/// OKI MR26V3211 (TSOP-II-44, 3.3V, 4 MiB) +/// OKI MR26V3211 (TSOP-II-44, 3.3V, 32 Mibit / 4 MiB) /// /// ``` /// use gbhwdb_model::parser::{self, LabelParser}; @@ -148,10 +150,10 @@ pub static OKI_MR26V3210: NomParser = NomParser { /// ``` pub static OKI_MR26V3211: NomParser = NomParser { name: "OKI MR26V3211", - f: |input| gba("M", "R26V3211F").parse(input), + f: |input| gba("M", "R26V3211F", "H2").parse(input), }; -/// OKI MR26V6413 (TSOP-II-44, 3.3V, 8 MiB) +/// OKI MR26V6413 (TSOP-II-44, 3.3V, 64 Mibit / 8 MiB) /// /// ``` /// use gbhwdb_model::parser::{self, LabelParser}; @@ -159,10 +161,10 @@ pub static OKI_MR26V3211: NomParser = NomParser { /// ``` pub static OKI_MR26V6413: NomParser = NomParser { name: "OKI MR26V6413", - f: |input| gba("M", "R26V6413G").parse(input), + f: |input| gba("M", "R26V6413G", "I2").parse(input), }; -/// OKI MR26V6414 (TSOP-II-44, 3.3V, 8 MiB) +/// OKI MR26V6414 (TSOP-II-44, 3.3V, 64 Mibit / 8 MiB) /// /// ``` /// use gbhwdb_model::parser::{self, LabelParser}; @@ -170,10 +172,10 @@ pub static OKI_MR26V6413: NomParser = NomParser { /// ``` pub static OKI_MR26V6414: NomParser = NomParser { name: "OKI MR26V6414", - f: |input| gba("M", "R26V6414G").parse(input), + f: |input| gba("M", "R26V6414G", "I2").parse(input), }; -/// OKI MR26V6415 (TSOP-II-44, 3.3V, 8 MiB) +/// OKI MR26V6415 (TSOP-II-44, 3.3V, 64 Mibit / 8 MiB) /// /// ``` /// use gbhwdb_model::parser::{self, LabelParser}; @@ -181,10 +183,10 @@ pub static OKI_MR26V6414: NomParser = NomParser { /// ``` pub static OKI_MR26V6415: NomParser = NomParser { name: "OKI MR26V6415", - f: |input| gba("M", "R26V6415G").parse(input), + f: |input| gba("M", "R26V6415G", "I2").parse(input), }; -/// OKI MR27V810 (TSOP-II-44, 3.3V, 1 MiB) +/// OKI MR27V810 (TSOP-II-44, 3.3V, 8 Mibit / 1 MiB) /// /// ``` /// use gbhwdb_model::parser::{self, LabelParser}; @@ -192,10 +194,10 @@ pub static OKI_MR26V6415: NomParser = NomParser { /// ``` pub static OKI_MR27V810: NomParser = NomParser { name: "OKI MR27V810", - f: |input| gba("M", "R27V810F").parse(input), + f: |input| gba("M", "R27V810F", "F2").parse(input), }; -/// OKI MR27V6416 (TSOP-II-44, 3.3V, 8 MiB) +/// OKI MR27V6416 (TSOP-II-44, 3.3V, 64 Mibit / 8 MiB) /// /// ``` /// use gbhwdb_model::parser::{self, LabelParser}; @@ -203,10 +205,10 @@ pub static OKI_MR27V810: NomParser = NomParser { /// ``` pub static OKI_MR27V6416: NomParser = NomParser { name: "OKI MR27V6416", - f: |input| gba("M", "R27V6416M").parse(input), + f: |input| gba("M", "R27V6416M", "I2").parse(input), }; -/// OKI MR27V12813 (TSOP-II-44, 3.3V, 16 MiB) +/// OKI MR27V12813 (TSOP-II-44, 3.3V, 128 Mibit / 16 MiB) /// /// ``` /// use gbhwdb_model::parser::{self, LabelParser}; @@ -214,10 +216,10 @@ pub static OKI_MR27V6416: NomParser = NomParser { /// ``` pub static OKI_MR27V12813: NomParser = NomParser { name: "OKI MR27V12813", - f: |input| gba("M", "R27V12813M").parse(input), + f: |input| gba("M", "R27V12813M", "J2").parse(input), }; -/// OKI SGB mask ROM +/// OKI SGB mask ROM, MSM534011 (SOP-32, 5V, 4 Mibit / 512 KiB) /// /// ``` /// use gbhwdb_model::parser::{self, LabelParser}; diff --git a/model/src/parser/samsung.rs b/model/src/parser/samsung.rs new file mode 100644 index 00000000..50ec7602 --- /dev/null +++ b/model/src/parser/samsung.rs @@ -0,0 +1,136 @@ +// SPDX-FileCopyrightText: Joonas Javanainen +// +// SPDX-License-Identifier: MIT + +use nom::{ + branch::alt, + bytes::streaming::tag, + character::{complete::one_of, streaming::char}, + combinator::{opt, recognize}, + error::ParseError, + sequence::tuple, + Parser, +}; + +use super::{ + for_nom::{alnum_uppers, cgb_rom_code, digits, dmg_rom_code, uppers}, + Manufacturer, MaskRom, NomParser, +}; + +fn gb_km23c_old<'a, E: ParseError<&'a str>>( + chip_type: &'static str, + package: Package, + unknown: &'static str, + unknown2: &'static str, +) -> impl Parser<&'a str, MaskRom, E> { + tuple(( + tag("SEC "), + recognize(tuple(( + tag("KM23C"), + tag(chip_type), + opt(one_of("ABCD")), + tag(package.code()), + ))), + char(' '), + alt((dmg_rom_code(), cgb_rom_code())), + char(' '), + tag(unknown), + char(' '), + tag(unknown2) + .and(digits(1)) + .and(alnum_uppers(2)) + .and(uppers(1)), + )) + .map(|(_, kind, _, rom_id, _, _, _, _)| MaskRom { + rom_id: String::from(rom_id), + chip_type: Some(String::from(kind)), + manufacturer: Some(Manufacturer::Samsung), + date_code: None, + }) +} + +fn gb_km23c_new<'a, E: ParseError<&'a str>>( + chip_type: &'static str, + package: Package, + unknown: &'static str, + unknown2: &'static str, +) -> impl Parser<&'a str, MaskRom, E> { + tuple(( + tag("SEC "), + recognize(tuple(( + tag("KM23C"), + tag(chip_type), + opt(one_of("ABCD")), + tag(package.code()), + ))), + char(' '), + alt((dmg_rom_code(), cgb_rom_code())), + char(' '), + tag(unknown), + char(' '), + recognize(tag(unknown2).and(digits(3)).and(uppers(2))), + )) + .map(|(_, kind, _, rom_id, _, _, _, _)| MaskRom { + rom_id: String::from(rom_id), + chip_type: Some(String::from(kind)), + manufacturer: Some(Manufacturer::Samsung), + date_code: None, + }) +} + +/// Samsung KM23C4000 (SOP-32, 5V, 4 Mibit / 512 KiB) +/// +/// ``` +/// use gbhwdb_model::parser::{self, LabelParser}; +/// assert!(parser::samsung::SAMSUNG_KM23C4000.parse("SEC KM23C4000DG DMG-ATEA-0 E1 KF5304U").is_ok()); +/// ``` +pub static SAMSUNG_KM23C4000: NomParser = NomParser { + name: "Samsung KM23C4000", + f: |input| gb_km23c_old("4000", Package::Sop, "E1", "KF5").parse(input), +}; + +/// Samsung KM23C8000 (SOP-32, 5V, 8 Mibit / 1 MiB) +/// +/// ``` +/// use gbhwdb_model::parser::{self, LabelParser}; +/// assert!(parser::samsung::SAMSUNG_KM23C8000.parse("SEC KM23C8000DG DMG-APSJ-0 F1 KFX3ALY").is_ok()); +/// assert!(parser::samsung::SAMSUNG_KM23C8000.parse("SEC KM23C8000DG DMG-AAUJ-1 F1 KFX331U").is_ok()); +/// ``` +pub static SAMSUNG_KM23C8000: NomParser = NomParser { + name: "Samsung KM23C8000", + f: |input| gb_km23c_old("8000", Package::Sop, "F1", "KFX").parse(input), +}; + +/// Samsung KM23C16120 (TSOP-II-44, 5V, 16 Mibit / 2 MiB) +/// +/// ``` +/// use gbhwdb_model::parser::{self, LabelParser}; +/// assert!(parser::samsung::SAMSUNG_KM23C16120.parse("SEC KM23C16120T DMG-ADQJ-0 G2 KF6402G").is_ok()); +/// assert!(parser::samsung::SAMSUNG_KM23C16120.parse("SEC KM23C16120DT DMG-AWLP-0 G2 KF6409G").is_ok()); +/// assert!(parser::samsung::SAMSUNG_KM23C16120.parse("SEC KM23C16120DT CGB-BHMJ-0 G2 K3N5C317GD").is_ok()); +/// ``` +pub static SAMSUNG_KM23C16120: NomParser = NomParser { + name: "Samsung KM23C16120", + f: |input| { + alt(( + gb_km23c_old("16120", Package::Tsop, "G2", "KF6"), + gb_km23c_new("16120", Package::Tsop, "G2", "K3N5C"), + )) + .parse(input) + }, +}; + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +enum Package { + Sop, + Tsop, +} + +impl Package { + pub const fn code(&self) -> &'static str { + match self { + Package::Sop => "G", + Package::Tsop => "T", + } + } +} diff --git a/model/src/parser/sgb_rom.rs b/model/src/parser/sgb_rom.rs index 849c5dee..70538a88 100644 --- a/model/src/parser/sgb_rom.rs +++ b/model/src/parser/sgb_rom.rs @@ -2,10 +2,10 @@ // // SPDX-License-Identifier: MIT -use super::{week2, year2, LabelParser, Manufacturer}; +use super::{week2, year2, LabelParser}; use crate::{ macros::{multi_parser, single_parser}, - parser::{fujitsu, nec, oki, toshiba, MaskRom, PartDateCode}, + parser::{fujitsu, nec, oki, sharp, toshiba, MaskRom, PartDateCode}, }; /// ``` @@ -49,60 +49,12 @@ pub fn unknown3() -> &'static impl LabelParser { ) } -/// Sharp SGB ROM -/// -/// ``` -/// use gbhwdb_model::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 { - single_parser!( - 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(MaskRom { - rom_id: c[1].to_owned(), - manufacturer: Some(Manufacturer::Sharp), - chip_type: Some(c[2].to_owned()), - date_code: Some(PartDateCode::YearWeek { - year: year2(&c[3])?, - week: week2(&c[4])?, - }), - }) - }, - ) -} - -/// Sharp SGB2 ROM -/// -/// ``` -/// use gbhwdb_model::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 { - single_parser!( - MaskRom, - r#"^©\ 1998\ Nintendo\ (SYS-SGB2-10)\ (LH[[:alnum:]]{4})[[:alnum:]]{2}\ ([0-9]{2})([0-9]{2})\ [A-Z]$"#, - move |c| { - Ok(MaskRom { - rom_id: c[1].to_owned(), - manufacturer: Some(Manufacturer::Sharp), - chip_type: Some(c[2].to_owned()), - date_code: Some(PartDateCode::YearWeek { - year: year2(&c[3])?, - week: week2(&c[4])?, - }), - }) - }, - ) -} - pub fn sgb_rom() -> &'static impl LabelParser { multi_parser!( MaskRom, &toshiba::TOSHIBA_SGB_ROM, - sharp_sgb(), - sharp_sgb2(), + &sharp::SHARP_SGB_ROM, + &sharp::SHARP_SGB2_ROM, &oki::OKI_SGB_ROM, &fujitsu::FUJITSU_SGB_ROM, unknown2(), diff --git a/model/src/parser/sharp.rs b/model/src/parser/sharp.rs index 0a03d7e5..692d169e 100644 --- a/model/src/parser/sharp.rs +++ b/model/src/parser/sharp.rs @@ -3,6 +3,7 @@ // SPDX-License-Identifier: MIT use nom::{ + branch::alt, bytes::streaming::tag, character::streaming::char, combinator::{opt, value}, @@ -12,8 +13,8 @@ use nom::{ }; use super::{ - for_nom::{alphas, year2_week2}, - GenericPart, Manufacturer, NomParser, + for_nom::{alnum_uppers, alphas, cgb_rom_code, digits, dmg_rom_code, uppers, year2_week2}, + GenericPart, Manufacturer, MaskRom, NomParser, }; /// ``` @@ -151,3 +152,411 @@ impl Package { } } } + +/// Sharp unknown mask ROM (glop top, 256 Kibit / 32 KiB) +/// +/// ``` +/// use gbhwdb_model::parser::{self, LabelParser}; +/// assert!(parser::sharp::SHARP_MASK_ROM_GLOP_TOP_28_256_KIBIT.parse("LR0G150 DMG-TRA-1 97141").is_ok()); +/// ``` +pub static SHARP_MASK_ROM_GLOP_TOP_28_256_KIBIT: NomParser = NomParser { + name: "Sharp mask ROM", + f: |input| { + tuple(( + tag("LR0G150"), + char(' '), + dmg_rom_code(), + char(' '), + year2_week2, + digits(1), + )) + .map(|(_, _, rom_id, _, date_code, _)| MaskRom { + rom_id: String::from(rom_id), + manufacturer: Some(Manufacturer::Sharp), + chip_type: None, + date_code: Some(date_code), + }) + .parse(input) + }, +}; + +fn lh53_ancient<'a, E: ParseError<&'a str>>( + kind: Option<&'static str>, + unknown: char, +) -> impl Parser<&'a str, MaskRom, E> { + tuple(( + dmg_rom_code(), + char(' '), + tag("SHARP JAPAN"), + char(' '), + year2_week2, + char(' '), + alphas(1), + char(' '), + char(unknown), + )) + .map(move |(rom_id, _, _, _, date_code, _, _, _, _)| MaskRom { + rom_id: String::from(rom_id), + manufacturer: Some(Manufacturer::Sharp), + chip_type: kind.map(String::from), + date_code: Some(date_code), + }) +} + +fn lh53_old<'a, E: ParseError<&'a str>>( + kind: Option<&'static str>, + unknown: &'static str, +) -> impl Parser<&'a str, MaskRom, E> { + tuple(( + dmg_rom_code(), + char(' '), + tag("SHARP JAPAN"), + char(' '), + tag(unknown), + char(' '), + year2_week2, + char(' '), + alphas(1), + )) + .map(move |(rom_id, _, _, _, _, _, date_code, _, _)| MaskRom { + rom_id: String::from(rom_id), + manufacturer: Some(Manufacturer::Sharp), + chip_type: kind.map(String::from), + date_code: Some(date_code), + }) +} + +fn lh53_new<'a, E: ParseError<&'a str>>( + model: impl Parser<&'a str, Option<&'a str>, E>, + unknown: &'static str, +) -> impl Parser<&'a str, MaskRom, E> { + tuple(( + alt((dmg_rom_code(), cgb_rom_code())), + tag(" S "), + model, + tag(" JAPAN "), + tag(unknown), + char(' '), + year2_week2, + char(' '), + alphas(1), + )) + .map(|(rom_id, _, kind, _, _, _, date_code, _, _)| MaskRom { + rom_id: String::from(rom_id), + manufacturer: Some(Manufacturer::Sharp), + chip_type: kind.map(String::from), + date_code: Some(date_code), + }) +} + +/// Sharp LH53259M mask ROM (QFP-44, 256 Kibit / 32 KiB) +/// +/// ``` +/// use gbhwdb_model::parser::{self, LabelParser}; +/// assert!(parser::sharp::SHARP_LH53259M.parse("DMG-AWA-0 SHARP JAPAN 8909 D A").is_ok()); +/// assert!(parser::sharp::SHARP_LH53259M.parse("DMG-AWA-0 SHARP JAPAN A0 8938 D").is_ok()); +/// assert!(parser::sharp::SHARP_LH53259M.parse("DMG-OPX-0 S LH5359UZ JAPAN A0 9722 D").is_ok()); +/// ``` +pub static SHARP_LH53259M: NomParser = NomParser { + name: "Sharp LH53259", + f: |input| { + alt(( + lh53_ancient(Some("LH53259"), 'A'), + lh53_old(Some("LH53259"), "A0"), + lh53_new( + // Sharp Memory Data Book 1992 + value(Some("LH53259"), tag("LH5359").and(alnum_uppers(2))), + "A0", + ), + )) + .parse(input) + }, +}; + +/// Sharp LH53515M mask ROM (QFP-44, 512 Kibit / 64 KiB) +/// +/// ``` +/// use gbhwdb_model::parser::{self, LabelParser}; +/// assert!(parser::sharp::SHARP_LH53515M.parse("DMG-CVJ-0 SHARP JAPAN B0 8941 D").is_ok()); +/// ``` +pub static SHARP_LH53515M: NomParser = NomParser { + name: "Sharp LH53515", + f: |input| lh53_old(Some("LH53515"), "B0").parse(input), +}; + +/// Sharp LH53514Z mask ROM (SOP-32, 512 Kibit / 64 KiB) +/// +/// ``` +/// use gbhwdb_model::parser::{self, LabelParser}; +/// assert!(parser::sharp::SHARP_LH53514Z.parse("DMG-AYJ-0 S LH5314H1 JAPAN B1 9014 E").is_ok()); +/// ``` +pub static SHARP_LH53514Z: NomParser = NomParser { + name: "Sharp LH53514", + f: |input| { + lh53_new( + // reasonable guess + value(Some("LH53514"), tag("LH5314").and(alnum_uppers(2))), + "B1", + ) + .parse(input) + }, +}; + +/// Sharp LH53517Z mask ROM (SOP-32, 512 Kibit / 64 KiB) +/// +/// ``` +/// use gbhwdb_model::parser::{self, LabelParser}; +/// assert!(parser::sharp::SHARP_LH53517Z.parse("DMG-AYNP-0 S LH5317VR JAPAN B1 9850 E").is_ok()); +/// ``` +pub static SHARP_LH53517Z: NomParser = NomParser { + name: "Sharp LH53517", + f: |input| { + lh53_new( + // reasonable guess + value(Some("LH53517"), tag("LH5317").and(alnum_uppers(2))), + "B1", + ) + .parse(input) + }, +}; + +/// Sharp LH530800N (SOP-32, 512 Kibit / 64 KiB) +/// +/// ``` +/// use gbhwdb_model::parser::{self, LabelParser}; +/// assert!(parser::sharp::SHARP_LH530800N.parse("DMG-A6W-0 S LH531HF8 JAPAN C1 9709 E").is_ok()); +/// ``` +pub static SHARP_LH530800N: NomParser = NomParser { + name: "Sharp LH530800", + f: |input| { + lh53_new( + alt(( + // reasonable guess + value(Some("LH530800"), tag("LH5308").and(alnum_uppers(2))), + // Sharp Memory Data Book 1992 + value(Some("LH530800A"), tag("LH531H").and(alnum_uppers(2))), + )), + "C1", + ) + .parse(input) + }, +}; + +/// Sharp unknown mask ROM (SOP-32, 1 Mibit / 128 KiB) +/// ``` +/// use gbhwdb_model::parser::{self, LabelParser}; +/// assert!(parser::sharp::SHARP_MASK_ROM_SOP_32_1_MIBIT.parse("DMG-NME-0 SHARP JAPAN C1 9009 E").is_ok()); +/// ``` +pub static SHARP_MASK_ROM_SOP_32_1_MIBIT: NomParser = NomParser { + name: "Sharp mask ROM", + f: |input| lh53_old(None, "C1").parse(input), +}; + +/// Sharp LH532100N mask ROM (SOP-32, 2 Mibit / 256 KiB) +/// ``` +/// use gbhwdb_model::parser::{self, LabelParser}; +/// assert!(parser::sharp::SHARP_LH532100N.parse("DMG-DFJ-0 S LH5321FL JAPAN D1 9249 D").is_ok()); +/// ``` +pub static SHARP_LH532100N: NomParser = NomParser { + name: "Sharp LH532100N", + f: |input| { + lh53_new( + value(Some("LH532100"), tag("LH5321").and(alnum_uppers(2))), + "D1", + ) + .parse(input) + }, +}; + +/// Sharp LH532xxxN mask ROM (SOP-32, 2 Mibit / 256 KiB) +/// ``` +/// use gbhwdb_model::parser::{self, LabelParser}; +/// assert!(parser::sharp::SHARP_LH532XXXN.parse("DMG-DIJ-0 S LH532D17 JAPAN D1 9223 D").is_ok()); +/// ``` +pub static SHARP_LH532XXXN: NomParser = NomParser { + // maybe: LH532100 series / LH532300 / LH532700 series + name: "Sharp LH532???", + f: |input| { + lh53_new( + value( + None, + alt(( + tag("LH532D"), + tag("LH532K"), + tag("LH532M"), + tag("LH532W"), + tag("LHMN2E"), + )) + .and(alnum_uppers(2)), + ), + "D1", + ) + .parse(input) + }, +}; + +/// Sharp LH534xxxN mask ROM (SOP-32, 4 Mibit / 512 KiB) +/// ``` +/// use gbhwdb_model::parser::{self, LabelParser}; +/// assert!(parser::sharp::SHARP_LH534XXXN.parse("DMG-A3ME-0 S LH534MW1 JAPAN E1 9547 E").is_ok()); +/// ``` +pub static SHARP_LH534XXXN: NomParser = NomParser { + // maybe: LH534100 series / LH534300 series / LH534R00 + name: "Sharp LH534???", + f: |input| { + lh53_new( + value( + None, + alt((tag("LH534M"), tag("LH5S4M"), tag("LHMN4M"))).and(alnum_uppers(2)), + ), + "E1", + ) + .parse(input) + }, +}; + +/// Sharp LH538xxxN mask ROM (SOP-32, 8 Mibit / 1 MiB) +/// ``` +/// use gbhwdb_model::parser::{self, LabelParser}; +/// assert!(parser::sharp::SHARP_LH538XXXN.parse("CGB-AHYE-0 S LH538WV9 JAPAN F1 9916 D").is_ok()); +/// ``` +pub static SHARP_LH538XXXN: NomParser = NomParser { + // maybe: LH538300 series / LH538400 series / LH538700 / LH538R00 series + name: "Sharp LH538???", + f: |input| { + lh53_new( + value( + None, + alt(( + tag("LH538M"), + tag("LH538W"), + tag("LH5S8M"), + tag("LHMN8J"), + tag("LHMN8M"), + )) + .and(alnum_uppers(2)), + ), + "F1", + ) + .parse(input) + }, +}; + +/// Sharp LH534xxxS mask ROM (TSOP-I-32, 4 Mibit / 512 KiB) +/// ``` +/// use gbhwdb_model::parser::{self, LabelParser}; +/// assert!(parser::sharp::SHARP_LH534XXXS.parse("DMG-HFAJ-0 S LHMN4MTI JAPAN E 9838 E").is_ok()); +/// ``` +pub static SHARP_LH534XXXS: NomParser = NomParser { + name: "Sharp LH534???", + f: |input| lh53_new(value(None, tag("LHMN4M").and(alnum_uppers(2))), "E").parse(input), +}; + +/// Sharp LH538xxxS mask ROM (TSOP-I-32, 8 Mibit / 1 MiB) +/// ``` +/// use gbhwdb_model::parser::{self, LabelParser}; +/// assert!(parser::sharp::SHARP_LH538XXXS.parse("DMG-HRCJ-0 S LH5S8MTI JAPAN F 9846 E").is_ok()); +/// ``` +pub static SHARP_LH538XXXS: NomParser = NomParser { + name: "Sharp LH538???", + f: |input| lh53_new(value(None, tag("LH5S8M").and(alnum_uppers(2))), "F").parse(input), +}; + +/// Sharp LH5316xxx mask ROM (TSOP-II-44, 16 Mibit / 2 MiB) +/// +/// ``` +/// use gbhwdb_model::parser::{self, LabelParser}; +/// assert!(parser::sharp::SHARP_LH5316XXX.parse("CGB-AFIP-0 S LH537MTJ JAPAN G2 9929 D").is_ok()); +/// ``` +pub static SHARP_LH5316XXX: NomParser = NomParser { + // maybe: LH5316400 / LH5316500 series / LH5316P00 series + name: "Sharp LH5316???", + f: |input| lh53_new(value(None, tag("LH537M").and(alnum_uppers(2))), "G2").parse(input), +}; + +/// Sharp LH5332xxx mask ROM (TSOP-II-44, 32 Mibit / 4 MiB) +/// +/// ``` +/// use gbhwdb_model::parser::{self, LabelParser}; +/// assert!(parser::sharp::SHARP_LH5332XXX.parse("CGB-AYQE-0 S LHMN5MTF JAPAN H2 0010 D").is_ok()); +/// ``` +pub static SHARP_LH5332XXX: NomParser = NomParser { + name: "Sharp LH5332???", + f: |input| lh53_new(value(None, tag("LHMN5M").and(alnum_uppers(2))), "H2").parse(input), +}; + +fn sgb_rom<'a, E: ParseError<&'a str>>( + model: impl Parser<&'a str, Option<&'a str>, E>, + rom_id: &'static str, +) -> impl Parser<&'a str, MaskRom, E> { + tuple(( + tag(rom_id), + tag(" © 1994 Nintendo "), + model, + char(' '), + year2_week2, + char(' '), + uppers(1), + )) + .map(|(rom_id, _, kind, _, date_code, _, _)| MaskRom { + rom_id: String::from(rom_id), + chip_type: kind.map(String::from), + manufacturer: Some(Manufacturer::Sharp), + date_code: Some(date_code), + }) +} + +/// Sharp SGB mask ROM +/// +/// ``` +/// use gbhwdb_model::parser::{self, LabelParser}; +/// assert!(parser::sharp::SHARP_SGB_ROM.parse("SYS-SGB-2 © 1994 Nintendo LH532M0M 9432 E").is_ok()); +/// assert!(parser::sharp::SHARP_SGB_ROM.parse("SYS-SGB-2 © 1994 Nintendo LH532KND 9432 E").is_ok()); +/// assert!(parser::sharp::SHARP_SGB_ROM.parse("SYS-SGB-NT © 1994 Nintendo LH532KN8 9416 D").is_ok()); +/// ``` +pub static SHARP_SGB_ROM: NomParser = NomParser { + name: "Sharp SGB ROM", + f: |input| { + alt(( + sgb_rom( + value(Some("LH532100B"), tag("LH532K").and(tag("N8"))), + "SYS-SGB-NT", + ), + sgb_rom( + value(Some("LH532100B"), tag("LH532K").and(tag("ND"))), + "SYS-SGB-2", + ), + sgb_rom(value(None, tag("LH532M").and(tag("0M"))), "SYS-SGB-2"), + )) + .parse(input) + }, +}; + +/// Sharp SGB2 mask ROM +/// +/// ``` +/// use gbhwdb_model::parser::{self, LabelParser}; +/// assert!(parser::sharp::SHARP_SGB2_ROM.parse("© 1998 Nintendo SYS-SGB2-10 LH5S4RY4 0003 D").is_ok()); +/// ``` +pub static SHARP_SGB2_ROM: NomParser = NomParser { + name: "Sharp SGB2 ROM", + f: |input| { + tuple(( + tag("© 1998 Nintendo "), + tag("SYS-SGB2-10"), + char(' '), + value(Some("LH534R00B"), tag("LH5S4R").and(tag("Y4"))), + char(' '), + year2_week2, + char(' '), + uppers(1), + )) + .map(|(_, rom_id, _, kind, _, date_code, _, _)| MaskRom { + rom_id: String::from(rom_id), + chip_type: kind.map(String::from), + manufacturer: Some(Manufacturer::Sharp), + date_code: Some(date_code), + }) + .parse(input) + }, +};