#!/usr/bin/env python

import struct
from chips import ram
#import StringIO

def load(f, MMU, PPUMMU):
    assert(f.read(4) == "NES\032")
    ROM_bank_count, VROM_bank_count, flags_0, flags_1, RAM_bank_count, display_flags = struct.unpack("BBBBBB", f.read(6)) 
    # ROM_bank_count in 16 kiB units.
    # VROM_bank_count in 8 kiB units.
    # RAM_bank_count in 8 kiB units. If =0, assume 1.
    if RAM_bank_count == 0:
        RAM_bank_count = 1
    #print("RBC", ROM_bank_count)
    """
    flags_0 bits: 
        #0: 1=vertical_mirroring, 0=horizontal_mirroring.
        #1: 1=battery-backed_RAM_at_$6000..$7FFF, 
        #2: 1=trainer_at_$7000..$71FF.
        #3: 1=four-screen_VRAM_layout.
        #4..#7: four lower bits of ROM Mapper Type.
    flags_1 bits:
        #0: 1=VS-System_cartridges.
        #1: reserved, 0
        #2: reserved, 0
        #3: reserved, 0
        #4..#7: four higher bits of ROM Mapper Type.
    display_flags bits:
        #0: 1=PAL, 0=NTSC
        #1..#7: reserved.
    """
    assert(f.read(6) == "\0\0\0\0\0\0") # reserved
    # that was a 16 byte header in total.
    #print(VROM_bank_count) # 0
    #print(RAM_bank_count) # 1
    #print(hex(flags_0)) # 0x10 <=> part of Nintendo MMC1
    #print(hex(flags_1)) # 0
    #print(hex(display_flags)) # 0
    for i in range(RAM_bank_count*8192//256): # FIXME dynamic size.
        MMU.add_real_page("RAM", i, ram.RAM())
    # first ROM seems to be at $8000 in memory (or $C000 for that matter).
    # then ROM banks, in ascending order. If a trainer is present, its 512 bytes precede the ROM bank contents.
    # then VROM banks, in ascending order.
    ROM_banks = [f.read(16384) for i in range(ROM_bank_count)]
    assert((flags_0 & (1 << 2)) == 0) # not sure where trainer data is, exactly.
    VROM_banks = [f.read(8192) for i in range(VROM_bank_count)]
    addr = 0x10000 - ROM_bank_count*16384
    #print(hex(addr)), ROM_bank_count
    for ROM_data in ROM_banks:
        #"$%X" % (addr,)
        MMU.map_ROM("CARTRIDGE", addr, ROM_data, True)
        addr += len(ROM_data)
    addr = 0
    print("VROM banks")
    for ROM_data in VROM_banks:
        #"$%X" % (addr,)
        PPUMMU.map_ROM("VROM", addr, ROM_data, True)
        addr += len(ROM_data)

if __name__ == "__main__":
    #IO = StringIO.StringIO()
    pass # load(IO, MMU)
