# from utils.utils import *
# # Circular import fix
# from typing import TYPE_CHECKING
# if TYPE_CHECKING:
#     from emulator import GA_Emulator

# Add memory maps from https://dn.odroid.com/S905X3/ODROID-C4/Docs/S905X3_Public_Datasheet_Hardkernel.pdf

memory_maps = '''
START END REGION (NORMAL)
FFFF0000 FFFFFFFF a55_rom
FFFE8000 FFFEFFFF reserved
FFFA0000 FFFE7FFF ahb sram
FFE80000 FFF9FFFF reserved
FFE40000 FFE7FFFF mali
FFE0D000 FFE3FFFF reserved
FFE0B000 FFE0CFFF reserved
FFE09000 FFE0AFFF usbctrl
FFE07000 FFE08FFF emmcC
FFE05000 FFE06FFF emmcB
FFE03000 FFE04FFF emmcA
FFE02000 FFE02FFF bt656
FFE01000 FFE01FFF htx_hdcp22
FFE00000 FFE00FFF reserved
FFD27000 FFDFFFFF reserved
FFD26000 FFD26FFF async_fifo3
FFD25000 FFD25FFF sc
FFD24000 FFD24FFF uart0
FFD23000 FFD23FFF uart1
FFD22000 FFD22FFF uart2
FFD21000 FFD21FFF reserved
FFD20000 FFD20FFF reserved
FFD1F000 FFD1FFFF i2c_m0
FFD1E000 FFD1EFFF i2c_m1
FFD1D000 FFD1DFFF i2c_m2
FFD1C000 FFD1CFFF i2c_m3
FFD1B000 FFD1BFFF pwm_ab
FFD1A000 FFD1AFFF pwm_cd
FFD19000 FFD19FFF pwm_ef
FFD18000 FFD18FFF msr_clk
FFD17000 FFD17FFF reserve
FFD16000 FFD16FFF reserved
FFD15000 FFD15FFF spicc_1
FFD14000 FFD14FFF spifc
FFD13000 FFD13FFF spicc_0
FFD12000 FFD12FFF reserved
FFD11000 FFD11FFF reserved
FFD10000 FFD10FFF reserved
FFD0F000 FFD0FFFF isa
FFD0E000 FFD0EFFF parser
FFD0D000 FFD0DFFF parser1
FFD0C000 FFD0CFFF sana
FFD0B000 FFD0BFFF stream
FFD0A000 FFD0AFFF async_fifo
FFD09000 FFD09FFF async_fifo2
FFD08000 FFD08FFF assist
FFD07000 FFD07FFF
FFD06000 FFD06FFF stb
FFD05000 FFD05FFF aififo
FFD04000 FFD04FFF reserved
FFD03000 FFD03FFF reserved
FFD02000 FFD02FFF reserved
FFD01000 FFD01FFF reset
FFD00000 FFD00FFF reserved
FFC08000 FFCFFFFF reserved
FFC00000 FFC07FFF gic
FFB00000 FFBFFFFF gpv
FF950000 FFAFFFFF reserved
FF940000 FF94FFFF ge2d
FF900000 FF93FFFF vpu
FF80B000 FF8FFFFF reserved
FF80A000 FF80AFFF ao_mailbox
FF809000 FF809FFF sar_adc
FF808000 FF808FFF ir_dec
FF807000 FF807FFF pwm_ab
FF806000 FF806FFF i2c_s
FF805000 FF805FFF i2c_m
FF804000 FF804FFF uart2
FF803000 FF803FFF uart
FF802000 FF802FFF pwm_cd
FF801000 FF801FFF reserved
FF800000 FF800FFF rti
FF664000 FF7FFFFF reserved
FF663800 FF663FFF
FF663000 FF6637FF
FF662000 FF662FFF eqdrc
FF661C00 FF661FFF resampleA
FF661800 FF661BFF vad
FF661400 FF6617FF locker
FF661000 FF6613FF pdm
FF660000 FF660FFF audiotop
FF652000 FF65FFFF reserved
FF650000 FF651FFF
FF64E000 FF64FFFF reset_sec
FF64C000 FF64DFFF eth_phy
FF64A000 FF64BFFF
FF648000 FF649FFF pcie_A
FF646000 FF647FFF pcie_phy
FF644000 FF645FFF
FF642000 FF643FFF
FF640000 FF641FFF pdm
FF63E000 FF63FFFF dma
FF63C000 FF63DFFF hiu
FF63A000 FF63BFFF usbphy21
FF638000 FF639FFF dmc
FF636000 FF637FFF usbphy20
FF635000 FF635FFF reserved
FF634C00 FF634FFF ts_ddr
FF634800 FF634BFF ts_pll
FF634400 FF6347FF periphs_reg
FF634000 FF6343FF reserved
FF632000 FF633FFF acodec
FF630000 FF631FFF efuse
FF620000 FF62FFFF dos
FF610000 FF61FFFF wavel
FF600000 FF60FFFF hdmitx
FF500000 FF5FFFFF usb0
FF400000 FF4FFFFF usb1
FF3F0000 FF3FFFFF eth
FF140000 FF3EFFFF reserved
FF100000 FF13FFFF NN
FF000000 FF0FFFFF reserved
FE000000 FEFFFFFF ddr_ctrl
FC000000 FDFFFFFF pcie_axi
FA000000 FBFFFFFF reserved
F6000000 F9FFFFFF flash
F5800000 F5FFFFFF a55_dbg
0 F57FFFFF ddr
'''

def find_memory(address):
    # ff800228
    for line in memory_maps.split("\n"):
        if line == "" or line == 'START END REGION (NORMAL)':
            continue
        items = line.split(" ")
        if len(items) >= 3:
            start, end, name = items[0], items[1], items[2]
        else:
            start, end = items[0], items[1]
            name = f"{start}_UNKNOWN"
        start = int(start, 16)
        end = int(end, 16)
        if address >= start and address <= end:
            print(f"{hex(start)}|{hex(end)}|{name}")
            break

def add_memory_maps(em : "GA_Emulator"):
    for line in memory_maps.split("\n"):
        if line == "" or line == 'START END REGION (NORMAL)':
            continue
        items = line.split(" ")
        if len(items) >= 3:
            start, end, name = items[0], items[1], items[2]
        else:
            start, end = items[0], items[1]
            name = f"{start}_UNKNOWN"
        start = int(start, 16)
        end = int(end, 16)
        # info(f"Mapping {name} at {hex(start)} with length: {hex(end - start)}")
        # Create empty dataset only if length is smaller than 64Kb
        if end - start > 0x10000:
            continue
        data = (end - start) * b"\x00"
        em.ghidra.add_memory(data, start, False, name, False)