// cartridge.h: interface for the CCartridge class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_CARTRIDGE_H__2E426BC5_EB72_43D5_BF5F_87BE5AC42EA3__INCLUDED_)
#define AFX_CARTRIDGE_H__2E426BC5_EB72_43D5_BF5F_87BE5AC42EA3__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "platform.h"
#include "Memory.h"
#include "mbc.h"

typedef struct _tag_licensee_t
{
    const char* code; // An hexadecimal value would work for most codes, but some of them.
    const char* name;  // (new licensees only) use other ascii characters.
} _licensee_t;

class CGBROMHeader
{
public:
	CGBROMHeader();
public:
	u8	m_cUnusedData[0x100];
	u8	m_cBeginCode[4]; //Usually there is a NOP and a JP instruction here but not always.
	u8	m_cScrollNintendoGraphic[0x30]; //PROGRAM WON'T RUN IF CHANGED!!!

	u8	m_cTitle[11]; //0134-0143 - Title of the game in UPPER CASE ASCII.
	u8	m_cManufacturer[4]; //In older games this is part of GameTime above, in newer games,
							//it's manufacturer
	u8	m_cGBCFlag; 
	//	00 or other = not Color GB
	//	80h - Game supports CGB functions, but works on old gameboys also.
	//	C0h - Game works on CGB only (physically the same as 80h).
	//Values with Bit 7 set, and either Bit 2 or 3 set, will switch the gameboy into a special 
	//non-CGB-mode with uninitialized palettes. Purpose unknown, eventually this has been 
	//supposed to be used to colorize monochrome games that include fixed palette data at a 
	//special location in ROM.

	//(0144,0145, These are normally $00 if [$014B](old license code) <> $33.)
	u8	m_cHiNibbleLic; //Ascii hex digit, high nibble of license code
	u8	m_cLoNibbleLic; //Ascii hex digit, low nibble of licensee code
	//These two bytes are used in newer games only (games that have been released after the SGB has been invented). 
	//Older games are using the header entry at 014B instead. 

	u8	m_SGBFlag; // (Super GameBoy functions won't work if <> $03.)
	//	00h = No SGB functions (Normal Gameboy or CGB only game) 
	//	03h = Game supports SGB functions

	u8	m_cCartridgeType;
	//	0-ROM ONLY             12-ROM+MBC3+RAM
    //	1-ROM+MBC1             13-ROM+MBC3+RAM+BATT
	//	2-ROM+MBC1+RAM         19-ROM+MBC5
	//	3-ROM+MBC1+RAM+BATT    1A-ROM+MBC5+RAM
	//	5-ROM+MBC2             1B-ROM+MBC5+RAM+BATT
	//	6-ROM+MBC2+BATTERY     1C-ROM+MBC5+RUMBLE
	//	8-ROM+RAM              1D-ROM+MBC5+RUMBLE+SRAM
	//	9-ROM+RAM+BATTERY      1E-ROM+MBC5+RUMBLE+SRAM+BATT
	//	B-ROM+MMM01            1F-Pocket Camera
	//	C-ROM+MMM01+SRAM       FD-Bandai TAMA5
    //	D-ROM+MMM01+SRAM+BATT  FE - Hudson HuC-3
	//	F-ROM+MBC3+TIMER+BATT  FF - Hudson HuC-1
	//	10-ROM+MBC3+TIMER+RAM+BATT
	//	11-ROM+MBC3

	u8	m_cROMSize; 
	//	0 - 256Kbit =  32KByte =   2 banks
	//	1 - 512Kbit =  64KByte =   4 banks
	//	2 -   1Mbit = 128KByte =   8 banks
	//	3 -   2Mbit = 256KByte =  16 banks
	//	4 -   4Mbit = 512KByte =  32 banks
	//	5 -   8Mbit =   1MByte =  64 banks
	//	6 -  16Mbit =   2MByte = 128 banks
	//	$52 -   9Mbit = 1.1MByte =  72 banks
	//	$53 -  10Mbit = 1.2MByte =  80 banks
    //  $54 -  12Mbit = 1.5MByte =  96 banks

	u8	m_cRAMSize;
	//	0 - None
	//	1 -  16kBit =  2kB = 1 bank
	//	2 -  64kBit =  8kB = 1 bank
	//	3 - 256kBit = 32kB = 4 banks
    //	4 -   1MBit =128kB =16 banks

	u8	m_cDestinationCode;
	//	0 - Japanese
	//	1 - Non-Japanese

	u8	m_cLicenseeCode_Old;
	//A value of 33h signalizes that the New License Code in header bytes 0144-0145(two nibble license code) is used instead. 
	//	33 - Check 0144/0145 for Licensee code.
	//	79 - Accolade
	//	A4 - Konami
	//	(Super GameBoy function won't work if <> $33.)

	u8	m_cROMVersion; //usually 0x00

	u8	m_cHeaderCheckSum;
	//(PROGRAM WON'T RUN ON GB IF NOT CORRECT!!!)
	//(It will run on Super GB, however, if incorrect.)

	u16	m_cGlobalCheckSum;
	//Checksum (higher byte first) produced by
	//adding all bytes of a cartridge except for
	//two checksum bytes and taking two lower
	//bytes of the result. (GameBoy ignores this value.)
};

class CGBMachine;

class CCartridge  
{
public:
	CCartridge();
	virtual ~CCartridge();
public:
	void SetMachine(CGBMachine* pMachine);
	const char* GetLicenseeName(u8 cHiCode, u8 u8LoCode);
	bool InsertRom(CGBROMHeader* pROMHeader);
	bool LoadRomFile(const char* sFilePath);

	bool IsRumbleEnable();
protected:
	CGBMachine*	m_pMachine;

	CMBC*		m_pMBC;
	
	int			m_nRAMBanks;
	int			m_nROMBanks;
};

#endif // !defined(AFX_CARTRIDGE_H__2E426BC5_EB72_43D5_BF5F_87BE5AC42EA3__INCLUDED_)
