diff --git a/addresses.lds b/addresses.lds index c5115e7..fb645f9 100644 --- a/addresses.lds +++ b/addresses.lds @@ -8,7 +8,7 @@ g2_if = 0xa05f7800; pvr_if = 0xa05f7c00; holly = 0xa05f8000; modem = 0xa0600000; -aica = 0xa0700000; +aica_sound = 0xa0700000; aica_rtc = 0xa0710000; system_boot_rom = 0xa0000000; diff --git a/aica/aica.hpp b/aica/aica.hpp index 463ed85..915264b 100644 --- a/aica/aica.hpp +++ b/aica/aica.hpp @@ -1,3 +1,5 @@ +#pragma once + #include #include @@ -8,7 +10,7 @@ #include "aica_common.hpp" #include "aica_rtc.hpp" -struct aica_reg { +struct aica_sound { // 0x00700000 [64] channel data start // 0x00702000 [64] channel data end // 0x00702000 [18] dsp out start @@ -22,10 +24,10 @@ struct aica_reg { struct aica_common common; }; -static_assert((sizeof (struct aica_reg)) == 0x2d08); -static_assert((offsetof (struct aica_reg, channel)) == 0); -static_assert((offsetof (struct aica_reg, dsp_out)) == 0x2000); -static_assert((offsetof (struct aica_reg, common)) == 0x2800); +static_assert((sizeof (struct aica_sound)) == 0x2d08); +static_assert((offsetof (struct aica_sound, channel)) == 0); +static_assert((offsetof (struct aica_sound, dsp_out)) == 0x2000); +static_assert((offsetof (struct aica_sound, common)) == 0x2800); -extern struct aica_reg aica __asm("aica"); +extern struct aica_sound aica_sound __asm("aica_sound"); extern struct aica_rtc aica_rtc __asm("aica_rtc"); diff --git a/aica/aica_channel.hpp b/aica/aica_channel.hpp index 36af3e0..cf38ec6 100644 --- a/aica/aica_channel.hpp +++ b/aica/aica_channel.hpp @@ -4,24 +4,78 @@ #include "type.hpp" struct aica_channel { - reg32 reg_0000; - reg32 reg_0004; - reg32 reg_0008; - reg32 reg_000c; - reg32 reg_0010; - reg32 reg_0014; - reg32 reg_0018; - reg32 reg_001c; - reg32 reg_0020; - reg32 reg_0024; - reg32 reg_0028; - reg32 reg_002c; - reg32 reg_0030; - reg32 reg_0034; - reg32 reg_0038; - reg32 reg_003c; - reg32 reg_0040; - reg32 reg_0044; + union { + reg32 reg_0000; + reg32 kyonex_kyonb_ssctl_lpctl_pcms_sa0; + }; + union { + reg32 reg_0004; + reg32 sa1; + }; + union { + reg32 reg_0008; + reg32 lsa; + }; + union { + reg32 reg_000c; + reg32 lea; + }; + union { + reg32 reg_0010; + reg32 d2r_d1r_ar; + }; + union { + reg32 reg_0014; + reg32 lpslnk_krs_dl_rr; + }; + union { + reg32 reg_0018; + reg32 oct_fns; + }; + union { + reg32 reg_001c; + reg32 lfore_lfof_plfows_plfos_alfows_alfos; + }; + union { + reg32 reg_0020; + reg32 imxl_isel; + }; + union { + reg32 reg_0024; + reg32 disdl_dipan; + }; + union { + reg32 reg_0028; + reg32 tl_voff_lpoff_q; + }; + union { + reg32 reg_002c; + reg32 flv0; + }; + union { + reg32 reg_0030; + reg32 flv1; + }; + union { + reg32 reg_0034; + reg32 flv2; + }; + union { + reg32 reg_0038; + reg32 flv3; + }; + union { + reg32 reg_003c; + reg32 flv4; + }; + union { + reg32 reg_0040; + reg32 far_fd1r; + }; + union { + reg32 reg_0044; + reg32 fd2r_frr; + }; const reg32 _pad0[14]; uint32_t KYONEX() const @@ -406,3 +460,83 @@ static_assert((offsetof (aica_channel, reg_0038)) == 0x38 - 0x0); static_assert((offsetof (aica_channel, reg_003c)) == 0x3c - 0x0); static_assert((offsetof (aica_channel, reg_0040)) == 0x40 - 0x0); static_assert((offsetof (aica_channel, reg_0044)) == 0x44 - 0x0); + +namespace aica { + namespace kyonex_kyonb_ssctl_lpctl_pcms_sa0 { + constexpr uint32_t KYONEX(const uint32_t v) { return (((v >> 0) & 0x1) << 15); } + constexpr uint32_t KYONB(const uint32_t v) { return (((v >> 0) & 0x1) << 14); } + constexpr uint32_t SSCTL(const uint32_t v) { return (((v >> 0) & 0x1) << 10); } + constexpr uint32_t LPCTL(const uint32_t v) { return (((v >> 0) & 0x1) << 9); } + constexpr uint32_t PCMS(const uint32_t v) { return (((v >> 0) & 0x3) << 7); } + constexpr uint32_t SA(const uint32_t v) { return (((v >> 16) & 0x7f) << 0); } + } + namespace sa1 { + constexpr uint32_t SA(const uint32_t v) { return (((v >> 0) & 0xffff) << 0); } + } + namespace lsa { + constexpr uint32_t LSA(const uint32_t v) { return (((v >> 0) & 0xffff) << 0); } + } + namespace lea { + constexpr uint32_t LEA(const uint32_t v) { return (((v >> 0) & 0xffff) << 0); } + } + namespace d2r_d1r_ar { + constexpr uint32_t D2R(const uint32_t v) { return (((v >> 0) & 0x1f) << 11); } + constexpr uint32_t D1R(const uint32_t v) { return (((v >> 0) & 0x1f) << 6); } + constexpr uint32_t AR(const uint32_t v) { return (((v >> 0) & 0x1f) << 0); } + } + namespace lpslnk_krs_dl_rr { + constexpr uint32_t LPSLNK(const uint32_t v) { return (((v >> 0) & 0x1) << 14); } + constexpr uint32_t KRS(const uint32_t v) { return (((v >> 0) & 0xf) << 10); } + constexpr uint32_t DL(const uint32_t v) { return (((v >> 0) & 0x1f) << 5); } + constexpr uint32_t RR(const uint32_t v) { return (((v >> 0) & 0x1f) << 0); } + } + namespace oct_fns { + constexpr uint32_t OCT(const uint32_t v) { return (((v >> 0) & 0xf) << 11); } + constexpr uint32_t FNS(const uint32_t v) { return (((v >> 0) & 0x3ff) << 0); } + } + namespace lfore_lfof_plfows_plfos_alfows_alfos { + constexpr uint32_t LFORE(const uint32_t v) { return (((v >> 0) & 0x1) << 15); } + constexpr uint32_t LFOF(const uint32_t v) { return (((v >> 0) & 0x1f) << 10); } + constexpr uint32_t PLFOWS(const uint32_t v) { return (((v >> 0) & 0x3) << 8); } + constexpr uint32_t PLFOS(const uint32_t v) { return (((v >> 0) & 0x7) << 5); } + constexpr uint32_t ALFOWS(const uint32_t v) { return (((v >> 0) & 0x3) << 3); } + constexpr uint32_t ALFOS(const uint32_t v) { return (((v >> 0) & 0x7) << 0); } + } + namespace imxl_isel { + constexpr uint32_t IMXL(const uint32_t v) { return (((v >> 0) & 0xf) << 4); } + constexpr uint32_t ISEL(const uint32_t v) { return (((v >> 0) & 0xf) << 0); } + } + namespace disdl_dipan { + constexpr uint32_t DISDL(const uint32_t v) { return (((v >> 0) & 0xf) << 8); } + constexpr uint32_t DIPAN(const uint32_t v) { return (((v >> 0) & 0x1f) << 0); } + } + namespace tl_voff_lpoff_q { + constexpr uint32_t TL(const uint32_t v) { return (((v >> 0) & 0xff) << 8); } + constexpr uint32_t VOFF(const uint32_t v) { return (((v >> 0) & 0x1) << 6); } + constexpr uint32_t LPOFF(const uint32_t v) { return (((v >> 0) & 0x1) << 5); } + constexpr uint32_t Q(const uint32_t v) { return (((v >> 0) & 0x1f) << 0); } + } + namespace flv0 { + constexpr uint32_t FLV0(const uint32_t v) { return (((v >> 0) & 0x1fff) << 0); } + } + namespace flv1 { + constexpr uint32_t FLV1(const uint32_t v) { return (((v >> 0) & 0x1fff) << 0); } + } + namespace flv2 { + constexpr uint32_t FLV2(const uint32_t v) { return (((v >> 0) & 0x1fff) << 0); } + } + namespace flv3 { + constexpr uint32_t FLV3(const uint32_t v) { return (((v >> 0) & 0x1fff) << 0); } + } + namespace flv4 { + constexpr uint32_t FLV4(const uint32_t v) { return (((v >> 0) & 0x1fff) << 0); } + } + namespace far_fd1r { + constexpr uint32_t FAR(const uint32_t v) { return (((v >> 0) & 0x1f) << 8); } + constexpr uint32_t FD1R(const uint32_t v) { return (((v >> 0) & 0x1f) << 0); } + } + namespace fd2r_frr { + constexpr uint32_t FD2R(const uint32_t v) { return (((v >> 0) & 0x1f) << 8); } + constexpr uint32_t FRR(const uint32_t v) { return (((v >> 0) & 0x1f) << 0); } + } +} diff --git a/aica/aica_common.hpp b/aica/aica_common.hpp index ac38b2a..fb144b3 100644 --- a/aica/aica_common.hpp +++ b/aica/aica_common.hpp @@ -4,34 +4,109 @@ #include "type.hpp" struct aica_common { - reg32 reg_2800; - reg32 reg_2804; - reg32 reg_2808; - reg32 reg_280c; - reg32 reg_2810; - reg32 reg_2814; + union { + reg32 reg_2800; + reg32 mono_mem8mb_dac18b_ver_mvol; + }; + union { + reg32 reg_2804; + reg32 rbl_rbp; + }; + union { + reg32 reg_2808; + reg32 moful_moemp_miovf_miful_miemp_mibuf; + }; + union { + reg32 reg_280c; + reg32 afsel_mslc_mobuf; + }; + union { + reg32 reg_2810; + reg32 lp_sgc_eg; + }; + union { + reg32 reg_2814; + reg32 ca; + }; const reg32 _pad0[26]; - reg32 reg_2880; - reg32 reg_2884; - reg32 reg_2888; - reg32 reg_288c; - reg32 reg_2890; - reg32 reg_2894; - reg32 reg_2898; - reg32 reg_289c; - reg32 reg_28a0; - reg32 reg_28a4; - reg32 reg_28a8; - reg32 reg_28ac; - reg32 reg_28b0; - reg32 reg_28b4; - reg32 reg_28b8; - reg32 reg_28bc; + union { + reg32 reg_2880; + reg32 dmea0_mrwinh; + }; + union { + reg32 reg_2884; + reg32 dmea1; + }; + union { + reg32 reg_2888; + reg32 dgate_drga; + }; + union { + reg32 reg_288c; + reg32 ddir_dlg_dexe; + }; + union { + reg32 reg_2890; + reg32 tactl_tima; + }; + union { + reg32 reg_2894; + reg32 tbctl_timb; + }; + union { + reg32 reg_2898; + reg32 tcctl_timc; + }; + union { + reg32 reg_289c; + reg32 scieb; + }; + union { + reg32 reg_28a0; + reg32 scipd; + }; + union { + reg32 reg_28a4; + reg32 scire; + }; + union { + reg32 reg_28a8; + reg32 scilv0; + }; + union { + reg32 reg_28ac; + reg32 scilv1; + }; + union { + reg32 reg_28b0; + reg32 scilv2; + }; + union { + reg32 reg_28b4; + reg32 mcieb; + }; + union { + reg32 reg_28b8; + reg32 mcipd; + }; + union { + reg32 reg_28bc; + reg32 mcire; + }; const reg32 _pad1[208]; - reg32 reg_2c00; + union { + reg32 reg_2c00; + reg32 vreg_armrst; + }; const reg32 _pad2[63]; - reg32 reg_2d00; - reg32 reg_2d04; + union { + reg32 reg_2d00; + reg32 l7_l6_l5_l4_l3_l2_l1_l0; + }; + union { + reg32 reg_2d04; + reg32 rp_m7_m6_m5_m4_m3_m2_m1_m0; + }; uint32_t MONO() const { @@ -78,15 +153,6 @@ struct aica_common { reg_2800 = (((v >> 0) & 0xf) << 0) | (reg_2800 & 0xfff0); } - uint32_t TESTB0() const - { - return (static_cast((reg_2804 >> 15) & 0x1) << 0); - } - void TESTB0(const uint32_t v) - { - reg_2804 = (((v >> 0) & 0x1) << 15) | (reg_2804 & 0x7fff); - } - uint32_t RBL() const { return (static_cast((reg_2804 >> 13) & 0x3) << 0); @@ -159,11 +225,11 @@ struct aica_common { reg_2808 = (((v >> 0) & 0xff) << 0) | (reg_2808 & 0xff00); } - uint32_t AFSET() const + uint32_t AFSEL() const { return (static_cast((reg_280c >> 14) & 0x1) << 0); } - void AFSET(const uint32_t v) + void AFSEL(const uint32_t v) { reg_280c = (((v >> 0) & 0x1) << 14) | (reg_280c & 0xbfff); } @@ -232,24 +298,6 @@ struct aica_common { reg_2884 = (((v >> 2) & 0x3fff) << 2); } - uint32_t TSCD() const - { - return (static_cast((reg_2880 >> 5) & 0x7) << 0); - } - void TSCD(const uint32_t v) - { - reg_2880 = (((v >> 0) & 0x7) << 5) | (reg_2880 & 0xff1f); - } - - uint32_t T() const - { - return (static_cast((reg_2880 >> 4) & 0x1) << 0); - } - void T(const uint32_t v) - { - reg_2880 = (((v >> 0) & 0x1) << 4) | (reg_2880 & 0xffef); - } - uint32_t MRWINH() const { return (static_cast((reg_2880 >> 0) & 0xf) << 0); @@ -421,11 +469,11 @@ struct aica_common { reg_28b4 = (((v >> 0) & 0x7ff) << 0); } - uint32_t MCIPB() const + uint32_t MCIPD() const { return (static_cast((reg_28b8 >> 0) & 0x7ff) << 0); } - void MCIPB(const uint32_t v) + void MCIPD(const uint32_t v) { reg_28b8 = (((v >> 0) & 0x7ff) << 0); } @@ -638,3 +686,118 @@ static_assert((offsetof (aica_common, reg_28bc)) == 0x28bc - 0x2800); static_assert((offsetof (aica_common, reg_2c00)) == 0x2c00 - 0x2800); static_assert((offsetof (aica_common, reg_2d00)) == 0x2d00 - 0x2800); static_assert((offsetof (aica_common, reg_2d04)) == 0x2d04 - 0x2800); + +namespace aica { + namespace mono_mem8mb_dac18b_ver_mvol { + constexpr uint32_t MONO(const uint32_t v) { return (((v >> 0) & 0x1) << 15); } + constexpr uint32_t MEM8MB(const uint32_t v) { return (((v >> 0) & 0x1) << 9); } + constexpr uint32_t DAC18B(const uint32_t v) { return (((v >> 0) & 0x1) << 8); } + constexpr uint32_t VER(const uint32_t reg) { return (static_cast((reg >> 4) & 0xf) << 0); } + constexpr uint32_t MVOL(const uint32_t v) { return (((v >> 0) & 0xf) << 0); } + } + namespace rbl_rbp { + constexpr uint32_t RBL(const uint32_t v) { return (((v >> 0) & 0x3) << 13); } + constexpr uint32_t RBP(const uint32_t v) { return (((v >> 11) & 0xfff) << 0); } + } + namespace moful_moemp_miovf_miful_miemp_mibuf { + constexpr uint32_t MOFUL(const uint32_t reg) { return (static_cast((reg >> 12) & 0x1) << 0); } + constexpr uint32_t MOEMP(const uint32_t reg) { return (static_cast((reg >> 11) & 0x1) << 0); } + constexpr uint32_t MIOVF(const uint32_t reg) { return (static_cast((reg >> 10) & 0x1) << 0); } + constexpr uint32_t MIFUL(const uint32_t reg) { return (static_cast((reg >> 9) & 0x1) << 0); } + constexpr uint32_t MIEMP(const uint32_t reg) { return (static_cast((reg >> 8) & 0x1) << 0); } + constexpr uint32_t MIBUF(const uint32_t reg) { return (static_cast((reg >> 0) & 0xff) << 0); } + } + namespace afsel_mslc_mobuf { + constexpr uint32_t AFSEL(const uint32_t v) { return (((v >> 0) & 0x1) << 14); } + constexpr uint32_t MSLC(const uint32_t v) { return (((v >> 0) & 0x3f) << 8); } + constexpr uint32_t MOBUF(const uint32_t v) { return (((v >> 0) & 0xff) << 0); } + } + namespace lp_sgc_eg { + constexpr uint32_t LP(const uint32_t reg) { return (static_cast((reg >> 15) & 0x1) << 0); } + constexpr uint32_t SGC(const uint32_t reg) { return (static_cast((reg >> 14) & 0x1) << 0); } + constexpr uint32_t EG(const uint32_t reg) { return (static_cast((reg >> 0) & 0x1fff) << 0); } + } + namespace ca { + constexpr uint32_t CA(const uint32_t reg) { return (static_cast((reg >> 0) & 0xffff) << 0); } + } + namespace dmea0_mrwinh { + constexpr uint32_t DMEA(const uint32_t v) { return (((v >> 16) & 0x7f) << 9); } + constexpr uint32_t MRWINH(const uint32_t v) { return (((v >> 0) & 0xf) << 0); } + } + namespace dmea1 { + constexpr uint32_t DMEA(const uint32_t v) { return (((v >> 2) & 0x3fff) << 2); } + } + namespace dgate_drga { + constexpr uint32_t DGATE(const uint32_t v) { return (((v >> 0) & 0x1) << 15); } + constexpr uint32_t DRGA(const uint32_t v) { return (((v >> 2) & 0x1fff) << 2); } + } + namespace ddir_dlg_dexe { + constexpr uint32_t DDIR(const uint32_t v) { return (((v >> 0) & 0x1) << 15); } + constexpr uint32_t DLG(const uint32_t v) { return (((v >> 2) & 0x1fff) << 2); } + constexpr uint32_t DEXE(const uint32_t v) { return (((v >> 0) & 0x1) << 0); } + } + namespace tactl_tima { + constexpr uint32_t TACTL(const uint32_t v) { return (((v >> 0) & 0x7) << 8); } + constexpr uint32_t TIMA(const uint32_t v) { return (((v >> 0) & 0xff) << 0); } + } + namespace tbctl_timb { + constexpr uint32_t TBCTL(const uint32_t v) { return (((v >> 0) & 0x7) << 8); } + constexpr uint32_t TIMB(const uint32_t v) { return (((v >> 0) & 0xff) << 0); } + } + namespace tcctl_timc { + constexpr uint32_t TCCTL(const uint32_t v) { return (((v >> 0) & 0x7) << 8); } + constexpr uint32_t TIMC(const uint32_t v) { return (((v >> 0) & 0xff) << 0); } + } + namespace scieb { + constexpr uint32_t SCIEB(const uint32_t v) { return (((v >> 0) & 0x7ff) << 0); } + } + namespace scipd { + constexpr uint32_t SCIPD(const uint32_t v) { return (((v >> 0) & 0x7ff) << 0); } + } + namespace scire { + constexpr uint32_t SCIRE(const uint32_t v) { return (((v >> 0) & 0x7ff) << 0); } + } + namespace scilv0 { + constexpr uint32_t SCILV0(const uint32_t v) { return (((v >> 0) & 0xff) << 0); } + } + namespace scilv1 { + constexpr uint32_t SCILV1(const uint32_t v) { return (((v >> 0) & 0xff) << 0); } + } + namespace scilv2 { + constexpr uint32_t SCILV2(const uint32_t v) { return (((v >> 0) & 0xff) << 0); } + } + namespace mcieb { + constexpr uint32_t MCIEB(const uint32_t v) { return (((v >> 0) & 0x7ff) << 0); } + } + namespace mcipd { + constexpr uint32_t MCIPD(const uint32_t v) { return (((v >> 0) & 0x7ff) << 0); } + } + namespace mcire { + constexpr uint32_t MCIRE(const uint32_t v) { return (((v >> 0) & 0x7ff) << 0); } + } + namespace vreg_armrst { + constexpr uint32_t VREG(const uint32_t v) { return (((v >> 0) & 0x3) << 8); } + constexpr uint32_t ARMRST(const uint32_t v) { return (((v >> 0) & 0x1) << 0); } + } + namespace l7_l6_l5_l4_l3_l2_l1_l0 { + constexpr uint32_t L7(const uint32_t reg) { return (static_cast((reg >> 7) & 0x1) << 0); } + constexpr uint32_t L6(const uint32_t reg) { return (static_cast((reg >> 6) & 0x1) << 0); } + constexpr uint32_t L5(const uint32_t reg) { return (static_cast((reg >> 5) & 0x1) << 0); } + constexpr uint32_t L4(const uint32_t reg) { return (static_cast((reg >> 4) & 0x1) << 0); } + constexpr uint32_t L3(const uint32_t reg) { return (static_cast((reg >> 3) & 0x1) << 0); } + constexpr uint32_t L2(const uint32_t reg) { return (static_cast((reg >> 2) & 0x1) << 0); } + constexpr uint32_t L1(const uint32_t reg) { return (static_cast((reg >> 1) & 0x1) << 0); } + constexpr uint32_t L0(const uint32_t reg) { return (static_cast((reg >> 0) & 0x1) << 0); } + } + namespace rp_m7_m6_m5_m4_m3_m2_m1_m0 { + constexpr uint32_t RP(const uint32_t v) { return (((v >> 0) & 0x1) << 8); } + constexpr uint32_t M7(const uint32_t v) { return (((v >> 0) & 0x1) << 7); } + constexpr uint32_t M6(const uint32_t v) { return (((v >> 0) & 0x1) << 6); } + constexpr uint32_t M5(const uint32_t v) { return (((v >> 0) & 0x1) << 5); } + constexpr uint32_t M4(const uint32_t v) { return (((v >> 0) & 0x1) << 4); } + constexpr uint32_t M3(const uint32_t v) { return (((v >> 0) & 0x1) << 3); } + constexpr uint32_t M2(const uint32_t v) { return (((v >> 0) & 0x1) << 2); } + constexpr uint32_t M1(const uint32_t v) { return (((v >> 0) & 0x1) << 1); } + constexpr uint32_t M0(const uint32_t v) { return (((v >> 0) & 0x1) << 0); } + } +} diff --git a/aica/aica_dsp_out.hpp b/aica/aica_dsp_out.hpp index f8c6305..0b19e11 100644 --- a/aica/aica_dsp_out.hpp +++ b/aica/aica_dsp_out.hpp @@ -4,7 +4,10 @@ #include "type.hpp" struct aica_dsp_out { - reg32 reg_0000; + union { + reg32 reg_0000; + reg32 efdsl_efpan; + }; uint32_t EFDSL() const { @@ -28,3 +31,10 @@ struct aica_dsp_out { static_assert((sizeof (aica_dsp_out)) == 0x4 - 0x0); static_assert((offsetof (aica_dsp_out, reg_0000)) == 0x0 - 0x0); + +namespace aica { + namespace efdsl_efpan { + constexpr uint32_t EFDSL(const uint32_t v) { return (((v >> 0) & 0xf) << 8); } + constexpr uint32_t EFPAN(const uint32_t v) { return (((v >> 0) & 0x1f) << 0); } + } +} diff --git a/aica/aica_rtc.hpp b/aica/aica_rtc.hpp index cf4598a..279af71 100644 --- a/aica/aica_rtc.hpp +++ b/aica/aica_rtc.hpp @@ -4,9 +4,18 @@ #include "type.hpp" struct aica_rtc { - reg32 reg_0000; - reg32 reg_0004; - reg32 reg_0008; + union { + reg32 reg_0000; + reg32 rtc0; + }; + union { + reg32 reg_0004; + reg32 rtc1; + }; + union { + reg32 reg_0008; + reg32 en; + }; uint32_t RTC() const { @@ -33,3 +42,15 @@ static_assert((sizeof (aica_rtc)) == 0xc - 0x0); static_assert((offsetof (aica_rtc, reg_0000)) == 0x0 - 0x0); static_assert((offsetof (aica_rtc, reg_0004)) == 0x4 - 0x0); static_assert((offsetof (aica_rtc, reg_0008)) == 0x8 - 0x0); + +namespace aica { + namespace rtc0 { + constexpr uint32_t RTC(const uint32_t v) { return (((v >> 16) & 0xffff) << 0); } + } + namespace rtc1 { + constexpr uint32_t RTC(const uint32_t v) { return (((v >> 0) & 0xffff) << 0); } + } + namespace en { + constexpr uint32_t EN(const uint32_t v) { return (((v >> 0) & 0x1) << 0); } + } +} diff --git a/example/aica.cpp b/example/aica.cpp index 4851143..9cf9164 100644 --- a/example/aica.cpp +++ b/example/aica.cpp @@ -1,8 +1,8 @@ #include "memorymap.hpp" -#include "aica/aica.hpp" #include "sh7091/serial.hpp" #include "systembus.hpp" #include "systembus_bits.hpp" +#include "aica/aica.hpp" extern void * _binary_start __asm("_binary_example_arm_channel_bin_start"); extern void * _binary_size __asm("_binary_example_arm_channel_bin_size"); @@ -27,35 +27,37 @@ void main() const uint32_t * binary = reinterpret_cast(&_binary_start); const uint32_t binary_size = reinterpret_cast(&_binary_size); - wait(); aica.common.reg_2c00 = 1; - wait(); aica.common.reg_2880 = 0; + wait(); aica_sound.common.vreg_armrst = aica::vreg_armrst::ARMRST(1); + wait(); aica_sound.common.dmea0_mrwinh = aica::dmea0_mrwinh::MRWINH(0); for (uint32_t i = 0; i < binary_size / 4; i++) { // copy - aica_wave_memory[i] = binary[i]; - if (i % 8 == 7) wait(); + while (aica_wave_memory[i] != binary[i]) { + wait(); + aica_wave_memory[i] = binary[i]; + } } - wait(); aica.common.reg_2c00 = 0; + wait(); aica_sound.common.vreg_armrst = aica::vreg_armrst::ARMRST(0); - serial::integer(aica_wave_memory[0]); - - wait(); aica.common.MSLC(0); + wait(); aica_sound.common.afsel_mslc_mobuf = aica::afsel_mslc_mobuf::MSLC(0); serial::string("mrwinh: "); wait_read(); - serial::integer(aica.common.MRWINH()); + serial::integer(aica_sound.common.MRWINH()); while (1) { wait_read(); serial::string("sgc: "); - serial::integer(aica.common.SGC(), ' '); + serial::integer(aica_sound.common.SGC(), ' '); serial::string("; ca: "); - serial::integer(aica.common.CA(), ' '); + serial::integer(aica_sound.common.CA(), ' '); serial::string("; eg: "); - serial::integer(aica.common.EG(), ' '); + serial::integer(aica_sound.common.EG(), ' '); serial::string("; lp: "); - serial::integer(aica.common.LP(), ' '); + serial::integer(aica_sound.common.LP(), ' '); serial::character('\n'); for (int i = 0; i < 10000000; i++) { asm volatile ("nop"); } + serial::integer(aica_wave_memory[0], ' '); + serial::integer(aica_wave_memory[1], '\n'); } while (1); diff --git a/example/aica_gdrom.cpp b/example/aica_gdrom.cpp new file mode 100644 index 0000000..4851143 --- /dev/null +++ b/example/aica_gdrom.cpp @@ -0,0 +1,62 @@ +#include "memorymap.hpp" +#include "aica/aica.hpp" +#include "sh7091/serial.hpp" +#include "systembus.hpp" +#include "systembus_bits.hpp" + +extern void * _binary_start __asm("_binary_example_arm_channel_bin_start"); +extern void * _binary_size __asm("_binary_example_arm_channel_bin_size"); + +void wait() +{ + while (ffst::aica_internal_write_buffer(system.FFST)); +} + +void wait_read() +{ + uint32_t ffst = ~0; + while ( ffst::holly_cpu_if_block_internal_write_buffer(ffst) + | ffst::holly_g2_if_block_internal_write_buffer(ffst) + | ffst::aica_internal_write_buffer(ffst)) { + ffst = system.FFST; + }; +} + +void main() +{ + const uint32_t * binary = reinterpret_cast(&_binary_start); + const uint32_t binary_size = reinterpret_cast(&_binary_size); + + wait(); aica.common.reg_2c00 = 1; + wait(); aica.common.reg_2880 = 0; + for (uint32_t i = 0; i < binary_size / 4; i++) { + // copy + aica_wave_memory[i] = binary[i]; + if (i % 8 == 7) wait(); + } + wait(); aica.common.reg_2c00 = 0; + + serial::integer(aica_wave_memory[0]); + + wait(); aica.common.MSLC(0); + serial::string("mrwinh: "); + wait_read(); + serial::integer(aica.common.MRWINH()); + while (1) { + wait_read(); + serial::string("sgc: "); + serial::integer(aica.common.SGC(), ' '); + serial::string("; ca: "); + serial::integer(aica.common.CA(), ' '); + serial::string("; eg: "); + serial::integer(aica.common.EG(), ' '); + serial::string("; lp: "); + serial::integer(aica.common.LP(), ' '); + serial::character('\n'); + for (int i = 0; i < 10000000; i++) { + asm volatile ("nop"); + } + } + + while (1); +} diff --git a/example/arm/addresses.lds b/example/arm/addresses.lds index bd61339..3b4f340 100644 --- a/example/arm/addresses.lds +++ b/example/arm/addresses.lds @@ -1,2 +1,2 @@ dram = 0x00000000; -aica = 0x00800000; +aica_sound = 0x00800000; diff --git a/example/arm/channel.cpp b/example/arm/channel.cpp index 41fb9d8..5c245a3 100644 --- a/example/arm/channel.cpp +++ b/example/arm/channel.cpp @@ -19,41 +19,46 @@ void main() dsp[i] = 0; } - aica.channel[0].KYONB(1); - aica.channel[0].LPCTL(1); - aica.channel[0].PCMS(0); - aica.channel[0].SA(sine_addr); - aica.channel[0].LSA(0); - aica.channel[0].LEA(128); - aica.channel[0].D2R(0x0); - aica.channel[0].D1R(0x0); - aica.channel[0].RR(0x0); - aica.channel[0].AR(0x1f); + aica_sound.channel[0].KYONB(1); + aica_sound.channel[0].LPCTL(1); + aica_sound.channel[0].PCMS(0); + aica_sound.channel[0].SA(sine_addr); + aica_sound.channel[0].LSA(0); + aica_sound.channel[0].LEA(128); + aica_sound.channel[0].D2R(0x0); + aica_sound.channel[0].D1R(0x0); + aica_sound.channel[0].RR(0x0); + aica_sound.channel[0].AR(0x1f); - aica.channel[0].OCT(0); - aica.channel[0].FNS(0); - aica.channel[0].DISDL(0xf); - aica.channel[0].DIPAN(0x0); + aica_sound.channel[0].OCT(0); + aica_sound.channel[0].FNS(0); + aica_sound.channel[0].DISDL(0xf); + aica_sound.channel[0].DIPAN(0x0); - aica.channel[0].Q(0b00100); - aica.channel[0].TL(0); - aica.channel[0].LPOFF(1); + aica_sound.channel[0].Q(0b00100); + aica_sound.channel[0].TL(0); + aica_sound.channel[0].LPOFF(1); - aica.common.MVOL(0xf); + aica_sound.common.MVOL(0xf); uint32_t segment = 0; - aica.common.TACTL(7); // increment once every 128 samples - aica.common.TIMA(0); - aica.channel[0].KYONEX(1); + aica_sound.common.TACTL(7); // increment once every 128 samples + aica_sound.common.TIMA(255); + aica_sound.channel[0].KYONEX(1); dram[0] = 0x11223344; - + dram[1] = sine_addr; + constexpr uint32_t timer_a_interrupt = (1 << 6); + aica_sound.common.scire = timer_a_interrupt; while (1) { - if (aica.common.TIMA() >= 1) { - aica.common.TIMA(0); + if (aica_sound.common.SCIPD() & timer_a_interrupt) { + aica_sound.common.scire = timer_a_interrupt; + aica_sound.common.TIMA(255); segment += 1; if (segment >= 3440) segment = 0; - aica.channel[0].SA(sine_addr + (128 * 2) * segment); + uint32_t sa = sine_addr + (128 * 2) * segment; + dram[1] = sa; + aica_sound.channel[0].SA(sa); } } } diff --git a/regs/aica_channel_data.csv b/regs/aica_channel_data.csv index 1a0a6c1..0375809 100644 --- a/regs/aica_channel_data.csv +++ b/regs/aica_channel_data.csv @@ -1,42 +1,42 @@ -"name","part","address","register_bits","argument_bits" -"KYONEX",,"0x0000","15", -"KYONB",,"0x0000","14", -"SSCTL",,"0x0000","10", -"LPCTL",,"0x0000","9", -"PCMS",,"0x0000","8-7", -"SA","0","0x0000","6-0","22-16" -"SA","1","0x0004","15-0", -"LSA",,"0x0008","15-0", -"LEA",,"0x000c","15-0", -"D2R",,"0x0010","15-11", -"D1R",,"0x0010","10-6", -"AR",,"0x0010","4-0", -"LPSLNK",,"0x0014","14", -"KRS",,"0x0014","13-10", -"DL",,"0x0014","9-5", -"RR",,"0x0014","4-0", -"OCT",,"0x0018","14-11", -"FNS",,"0x0018","9-0", -"LFORE",,"0x001c","15", -"LFOF",,"0x001c","14-10", -"PLFOWS",,"0x001c","9-8", -"PLFOS",,"0x001c","7-5", -"ALFOWS",,"0x001c","4-3", -"ALFOS",,"0x001c","2-0", -"IMXL",,"0x0020","7-4", -"ISEL",,"0x0020","3-0", -"DISDL",,"0x0024","11-8", -"DIPAN",,"0x0024","4-0", -"TL",,"0x0028","15-8", -"VOFF",,"0x0028","6", -"LPOFF",,"0x0028","5", -"Q",,"0x0028","4-0", -"FLV0",,"0x002c","12-0", -"FLV1",,"0x0030","12-0", -"FLV2",,"0x0034","12-0", -"FLV3",,"0x0038","12-0", -"FLV4",,"0x003c","12-0", -"FAR",,"0x0040","12-8", -"FD1R",,"0x0040","4-0", -"FD2R",,"0x0044","12-8", -"FRR",,"0x0044","4-0", +"name","part","address","register_bits","argument_bits","rw" +"KYONEX",,"0x0000","15",,"w" +"KYONB",,"0x0000","14",,"rw" +"SSCTL",,"0x0000","10",,"rw" +"LPCTL",,"0x0000","9",,"rw" +"PCMS",,"0x0000","8-7",,"rw" +"SA","0","0x0000","6-0","22-16","rw" +"SA","1","0x0004","15-0",,"rw" +"LSA",,"0x0008","15-0",,"rw" +"LEA",,"0x000c","15-0",,"rw" +"D2R",,"0x0010","15-11",,"rw" +"D1R",,"0x0010","10-6",,"rw" +"AR",,"0x0010","4-0",,"rw" +"LPSLNK",,"0x0014","14",,"rw" +"KRS",,"0x0014","13-10",,"rw" +"DL",,"0x0014","9-5",,"rw" +"RR",,"0x0014","4-0",,"rw" +"OCT",,"0x0018","14-11",,"rw" +"FNS",,"0x0018","9-0",,"rw" +"LFORE",,"0x001c","15",,"rw" +"LFOF",,"0x001c","14-10",,"rw" +"PLFOWS",,"0x001c","9-8",,"rw" +"PLFOS",,"0x001c","7-5",,"rw" +"ALFOWS",,"0x001c","4-3",,"rw" +"ALFOS",,"0x001c","2-0",,"rw" +"IMXL",,"0x0020","7-4",,"rw" +"ISEL",,"0x0020","3-0",,"rw" +"DISDL",,"0x0024","11-8",,"rw" +"DIPAN",,"0x0024","4-0",,"rw" +"TL",,"0x0028","15-8",,"rw" +"VOFF",,"0x0028","6",,"rw" +"LPOFF",,"0x0028","5",,"rw" +"Q",,"0x0028","4-0",,"rw" +"FLV0",,"0x002c","12-0",,"rw" +"FLV1",,"0x0030","12-0",,"rw" +"FLV2",,"0x0034","12-0",,"rw" +"FLV3",,"0x0038","12-0",,"rw" +"FLV4",,"0x003c","12-0",,"rw" +"FAR",,"0x0040","12-8",,"rw" +"FD1R",,"0x0040","4-0",,"rw" +"FD2R",,"0x0044","12-8",,"rw" +"FRR",,"0x0044","4-0",,"rw" diff --git a/regs/aica_channel_data.ods b/regs/aica_channel_data.ods index 7add0c2..39ced0f 100644 Binary files a/regs/aica_channel_data.ods and b/regs/aica_channel_data.ods differ diff --git a/regs/aica_common_data.csv b/regs/aica_common_data.csv index f9b3969..fa9a54b 100644 --- a/regs/aica_common_data.csv +++ b/regs/aica_common_data.csv @@ -1,66 +1,66 @@ -"name","part","address","register_bits","argument_bits" -"MONO",,"0x2800","15", -"MEM8MB",,"0x2800","9", -"DAC18B",,"0x2800","8", -"VER",,"0x2800","7-4", -"MVOL",,"0x2800","3-0", -"TESTB0",,"0x2804","15", -"RBL",,"0x2804","14-13", -"RBP",,"0x2804","11-0","22-11" -"MOFUL",,"0x2808","12", -"MOEMP",,"0x2808","11", -"MIOVF",,"0x2808","10", -"MIFUL",,"0x2808","9", -"MIEMP",,"0x2808","8", -"MIBUF",,"0x2808","7-0", -"AFSET",,"0x280c","14", -"MSLC",,"0x280c","13-8", -"MOBUF",,"0x280c","7-0", -"LP",,"0x2810","15", -"SGC",,"0x2810","14", -"EG",,"0x2810","12-0", -"CA",,"0x2814","15-0", -"DMEA","0","0x2880","15-9","22-16" -"TSCD",,"0x2880","7-5", -"T",,"0x2880","4", -"MRWINH",,"0x2880","3-0", -"DMEA","1","0x2884","15-2","15-2" -"DGATE",,"0x2888","15", -"DRGA",,"0x2888","14-2","14-2" -"DDIR",,"0x288c","15", -"DLG",,"0x288c","14-2","14-2" -"DEXE",,"0x288c","0", -"TACTL",,"0x2890","10-8", -"TIMA",,"0x2890","7-0", -"TBCTL",,"0x2894","10-8", -"TIMB",,"0x2894","7-0", -"TCCTL",,"0x2898","10-8", -"TIMC",,"0x2898","7-0", -"SCIEB",,"0x289c","10-0", -"SCIPD",,"0x28a0","10-0", -"SCIRE",,"0x28a4","10-0", -"SCILV0",,"0x28a8","7-0", -"SCILV1",,"0x28ac","7-0", -"SCILV2",,"0x28b0","7-0", -"MCIEB",,"0x28b4","10-0", -"MCIPB",,"0x28b8","10-0", -"MCIRE",,"0x28bc","10-0", -"VREG",,"0x2c00","9-8", -"ARMRST",,"0x2c00","0", -"L7",,"0x2d00","7", -"L6",,"0x2d00","6", -"L5",,"0x2d00","5", -"L4",,"0x2d00","4", -"L3",,"0x2d00","3", -"L2",,"0x2d00","2", -"L1",,"0x2d00","1", -"L0",,"0x2d00","0", -"RP",,"0x2d04","8", -"M7",,"0x2d04","7", -"M6",,"0x2d04","6", -"M5",,"0x2d04","5", -"M4",,"0x2d04","4", -"M3",,"0x2d04","3", -"M2",,"0x2d04","2", -"M1",,"0x2d04","1", -"M0",,"0x2d04","0", +"name","part","address","register_bits","argument_bits","rw" +"MONO",,"0x2800","15",,"w" +"MEM8MB",,"0x2800","9",,"w" +"DAC18B",,"0x2800","8",,"w" +"VER",,"0x2800","7-4",,"r" +"MVOL",,"0x2800","3-0",,"w" +"TESTB0",,"0x2804","15",, +"RBL",,"0x2804","14-13",,"w" +"RBP",,"0x2804","11-0","22-11","w" +"MOFUL",,"0x2808","12",,"r" +"MOEMP",,"0x2808","11",,"r" +"MIOVF",,"0x2808","10",,"r" +"MIFUL",,"0x2808","9",,"r" +"MIEMP",,"0x2808","8",,"r" +"MIBUF",,"0x2808","7-0",,"r" +"AFSEL",,"0x280c","14",,"w" +"MSLC",,"0x280c","13-8",,"w" +"MOBUF",,"0x280c","7-0",,"w" +"LP",,"0x2810","15",,"r" +"SGC",,"0x2810","14",,"r" +"EG",,"0x2810","12-0",,"r" +"CA",,"0x2814","15-0",,"r" +"DMEA","0","0x2880","15-9","22-16","w" +"TSCD",,"0x2880","7-5",, +"T",,"0x2880","4",, +"MRWINH",,"0x2880","3-0",,"w" +"DMEA","1","0x2884","15-2","15-2","w" +"DGATE",,"0x2888","15",,"rw" +"DRGA",,"0x2888","14-2","14-2","w" +"DDIR",,"0x288c","15",,"rw" +"DLG",,"0x288c","14-2","14-2","w" +"DEXE",,"0x288c","0",,"rw" +"TACTL",,"0x2890","10-8",,"w" +"TIMA",,"0x2890","7-0",,"w" +"TBCTL",,"0x2894","10-8",,"w" +"TIMB",,"0x2894","7-0",,"w" +"TCCTL",,"0x2898","10-8",,"w" +"TIMC",,"0x2898","7-0",,"w" +"SCIEB",,"0x289c","10-0",,"rw" +"SCIPD",,"0x28a0","10-0",,"rw" +"SCIRE",,"0x28a4","10-0",,"w" +"SCILV0",,"0x28a8","7-0",,"w" +"SCILV1",,"0x28ac","7-0",,"w" +"SCILV2",,"0x28b0","7-0",,"w" +"MCIEB",,"0x28b4","10-0",,"rw" +"MCIPD",,"0x28b8","10-0",,"rw" +"MCIRE",,"0x28bc","10-0",,"w" +"VREG",,"0x2c00","9-8",,"rw" +"ARMRST",,"0x2c00","0",,"rw" +"L7",,"0x2d00","7",,"r" +"L6",,"0x2d00","6",,"r" +"L5",,"0x2d00","5",,"r" +"L4",,"0x2d00","4",,"r" +"L3",,"0x2d00","3",,"r" +"L2",,"0x2d00","2",,"r" +"L1",,"0x2d00","1",,"r" +"L0",,"0x2d00","0",,"r" +"RP",,"0x2d04","8",,"w" +"M7",,"0x2d04","7",,"w" +"M6",,"0x2d04","6",,"w" +"M5",,"0x2d04","5",,"w" +"M4",,"0x2d04","4",,"w" +"M3",,"0x2d04","3",,"w" +"M2",,"0x2d04","2",,"w" +"M1",,"0x2d04","1",,"w" +"M0",,"0x2d04","0",,"w" diff --git a/regs/aica_common_data.ods b/regs/aica_common_data.ods index 8cb9e2d..b024189 100644 Binary files a/regs/aica_common_data.ods and b/regs/aica_common_data.ods differ diff --git a/regs/aica_dsp_out_data.csv b/regs/aica_dsp_out_data.csv index aabf8fd..c27325d 100644 --- a/regs/aica_dsp_out_data.csv +++ b/regs/aica_dsp_out_data.csv @@ -1,3 +1,3 @@ -"name","part","address","register_bits","argument_bits" -"EFDSL",,"0x0000","11-8", -"EFPAN",,"0x0000","4-0", +"name","part","address","register_bits","argument_bits","rw" +"EFDSL",,"0x0000","11-8",,"rw" +"EFPAN",,"0x0000","4-0",,"rw" diff --git a/regs/aica_dsp_out_data.ods b/regs/aica_dsp_out_data.ods index 00e54cc..547642c 100644 Binary files a/regs/aica_dsp_out_data.ods and b/regs/aica_dsp_out_data.ods differ diff --git a/regs/aica_rtc_data.csv b/regs/aica_rtc_data.csv index 92e55b6..91efac4 100644 --- a/regs/aica_rtc_data.csv +++ b/regs/aica_rtc_data.csv @@ -1,4 +1,4 @@ -"name","part","address","register_bits","argument_bits" -"RTC","0","0x0000","15-0","31-16" -"RTC","1","0x0004","15-0","15-0" -"EN",,"0x0008","0", +"name","part","address","register_bits","argument_bits","rw" +"RTC","0","0x0000","15-0","31-16","rw" +"RTC","1","0x0004","15-0","15-0","rw" +"EN",,"0x0008","0",,"w" diff --git a/regs/aica_rtc_data.ods b/regs/aica_rtc_data.ods index 05827ab..ccc81e0 100644 Binary files a/regs/aica_rtc_data.ods and b/regs/aica_rtc_data.ods differ diff --git a/regs/gen/aica.py b/regs/gen/aica.py index f9ffb84..dc0f1e6 100644 --- a/regs/gen/aica.py +++ b/regs/gen/aica.py @@ -15,6 +15,7 @@ class Part: @dataclass class Register: name: str + rw: set[str] parts: list[Part] def parse_slice(s): @@ -51,7 +52,8 @@ def parse_row(row): register_bits, argument_bits, ) - return name, part + rw = set(row["rw"]) + return name, rw, part def group_parts(rows, address_increment): by_name: dict[str, Register] = {} @@ -60,17 +62,20 @@ def group_parts(rows, address_increment): register_order = [] addresses = [] last_address = 0 + parts_by_register_name: dict[str, list] = defaultdict(list) for row in rows: - name, part = parse_row(row) + name, rw, part = parse_row(row) + if rw == set(): + continue assert part.address >= last_address, row assert part.address % address_increment == 0, row last_address = part.address if part.address not in set(a[0] for a in addresses): - addresses.append((part.address, [name])) + addresses.append((part.address, [(name, part.index)])) else: assert addresses[-1][0] == part.address - addresses[-1][1].append(name) + addresses[-1][1].append((name, part.index)) bits = slice_bits(part.register_bits) assert bits.intersection(register_bit_alloc[part.address]) == set(), row @@ -82,24 +87,33 @@ def group_parts(rows, address_increment): if name not in by_name: assert part.index == 0, row - register = Register(name, [part]) + register = Register(name, rw, [part]) by_name[name] = register register_order.append(register) else: assert len(by_name[name].parts) == part.index by_name[name].parts.append(part) - return addresses, register_order + parts_by_register_name[name].append(part.index) + + return addresses, register_order, parts_by_register_name def format_reg(address): return f"reg_{address:04x}" -def render_struct_fields(struct_size, addresses, address_increment, c_type, c_type_size): +def format_reg_friendly_name(names, parts_by_register_name): + return "_".join( + name.lower() if len(parts_by_register_name[name]) == 1 + else f"{name.lower()}{part_index}" + for name, part_index in names + ) + +def render_struct_fields(struct_size, addresses, address_increment, c_type, c_type_size, parts_by_register_name): assert address_increment >= c_type_size assert address_increment % c_type_size == 0 next_address = None pad_index = 0 - for address, _ in addresses: + for address, names in addresses: if next_address is None: next_address = address if address != next_address: @@ -108,7 +122,12 @@ def render_struct_fields(struct_size, addresses, address_increment, c_type, c_ty yield f"const {c_type} _pad{pad_index}[{padding}];" pad_index += 1 + # render the actual field + yield "union {" yield f"{c_type} {format_reg(address)};" + yield f"{c_type} {format_reg_friendly_name(names, parts_by_register_name)};" + yield "};" + if c_type_size < address_increment: padding = (address_increment - c_type_size) // c_type_size yield f"const {c_type} _pad{pad_index}[{padding}];" @@ -136,17 +155,23 @@ def mask_from_bits(bit_slice): mask = 2 ** ((h - l) + 1) - 1 return mask -def part_get_expression(part): +def part_get_expression(part, value=None): _, reg_end = part.register_bits _, arg_end = part.argument_bits arg_mask = mask_from_bits(part.argument_bits) - return f"(static_cast(({format_reg(part.address)} >> {reg_end}) & {hex(arg_mask)}) << {arg_end})" + value_expression = format_reg(part.address) if value is None else value + return f"(static_cast(({value_expression} >> {reg_end}) & {hex(arg_mask)}) << {arg_end})" + +def part_set_expression(part): + _, reg_end = part.register_bits + _, arg_end = part.argument_bits + arg_mask = mask_from_bits(part.argument_bits) + expression = f"(((v >> {arg_end}) & {hex(arg_mask)}) << {reg_end})" + return expression def part_set_statement(addresses_dict, c_type_real_size, part): _, reg_end = part.register_bits - _, arg_end = part.argument_bits - arg_mask = mask_from_bits(part.argument_bits) - assignment = f"{format_reg(part.address)} = (((v >> {arg_end}) & {hex(arg_mask)}) << {reg_end})" + assignment = f"{format_reg(part.address)} = {part_set_expression(part)}" if len(addresses_dict[part.address]) > 1: reg_mask = mask_from_bits(part.register_bits) << reg_end inverse_mask = (~reg_mask) & ((2 ** (c_type_real_size * 8)) - 1) @@ -169,14 +194,40 @@ def render_struct_accessors(addresses_dict, c_type, c_type_real_size, registers) yield "}" yield "" -def render_struct(struct_name, struct_size, addresses, address_increment, c_type, c_type_size, c_type_real_size, registers): +def render_bits(addresses_dict, registers, parts_by_register_name): + parts_by_address = defaultdict(list) + + for register in registers: + for part in register.parts: + parts_by_address[part.address].append((register, part)) + + for address, names in addresses_dict.items(): + namespace = format_reg_friendly_name(names, parts_by_register_name) + yield f"namespace {namespace} {{" + for register, part in parts_by_address[address]: + if 'w' in register.rw: + arg = "v" + expression = part_set_expression(part) + elif 'r' in register.rw: + arg = "reg" + expression = part_get_expression(part, arg) + else: + continue + yield f"constexpr uint32_t {register.name}(const uint32_t {arg}) {{ return {expression}; }}"; + yield "}" + +def render_struct(struct_name, struct_size, addresses, address_increment, c_type, c_type_size, c_type_real_size, registers, parts_by_register_name): yield f"struct {struct_name} {{" - yield from render_struct_fields(struct_size, addresses, address_increment, c_type, c_type_size) + yield from render_struct_fields(struct_size, addresses, address_increment, c_type, c_type_size, parts_by_register_name) yield "" addresses_dict = dict(addresses) yield from render_struct_accessors(addresses_dict, c_type, c_type_real_size, registers) yield "};" yield from render_struct_static_assertions(struct_name, struct_size, addresses, address_increment) + yield "" + yield f"namespace aica {{" + yield from render_bits(addresses_dict, registers, parts_by_register_name) + yield "}" def header(): yield '#include ' @@ -194,8 +245,8 @@ if __name__ == "__main__": c_type = "reg32" c_type_size = 4 c_type_real_size = 2 - addresses, registers = group_parts(rows, address_increment) + addresses, registers, parts_by_register_name = group_parts(rows, address_increment) render, out = renderer() render(header()) - render(render_struct(struct_name, struct_size, addresses, address_increment, c_type, c_type_size, c_type_real_size, registers)) + render(render_struct(struct_name, struct_size, addresses, address_increment, c_type, c_type_size, c_type_real_size, registers, parts_by_register_name)) sys.stdout.write(out.getvalue())