/*
 * Copyright (c) 2021-2023 Rupert Carmichael
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#ifndef CEGA_SMS_H
#define CEGA_SMS_H

#define SIZE_SMSRAM SIZE_8K

// Mappers
#define SMS_MAPPER_BIOS             0x00 // BIOS Mapper
#define SMS_MAPPER_SEGA             0x01 // Sega Mapper
#define SMS_MAPPER_CM               0x02 // Codemasters Mapper
#define SMS_MAPPER_JANGGUN          0x03 // Janggun Mapper
#define SMS_MAPPER_KOREA            0x04 // "Korea" Mapper
#define SMS_MAPPER_MSX              0x05 // MSX Mapper (Korea)
#define SMS_MAPPER_NEMESIS          0x06 // Nemesis Mapper (MSX Mapper Variant)
#define SMS_MAPPER_NONE             0x07 // No Mapper
#define SMS_MAPPER_4PAA             0x08 // 4 PAK All Action Mapper
#define SMS_MAPPER_XIN1             0x09 // X in 1 Mapper (3 in 1 and 8 in 1)
#define SMS_MAPPER_93C46            0x0a // 93C46 EEPROM Mapper (Game Gear)
#define SMS_MAPPER_KR_2000_XOR_1F   0x0b // Korean 2000 XOR 1F Mapper
#define SMS_MAPPER_KR_MSX_8KB_0300  0x0c // Korean MSX 8KB 0300 Mapper
#define SMS_MAPPER_KR_BFFC          0x0d // Korean BFFC Mapper
#define SMS_MAPPER_KR_FFFE          0x0e // Korean FFFE Mapper
#define SMS_MAPPER_KR_FFF5          0x0f // Korean FFF5 Mapper
#define SMS_MAPPER_EMPTY            0xff // Empty Slot

typedef struct _sms_sys_t {
    uint8_t ram[SIZE_SMSRAM]; // System RAM
    uint8_t cartram[SIZE_32K]; // Cartridge RAM
    uint8_t ggreg[6]; // Game Gear Registers (Serial I/O and Start Button)
    uint8_t ctrl[2]; // Controller Input state
    uint8_t port3e; // Memory Control Register
    uint8_t port3f; // IO Control Register
    uint8_t fmctrl; // FM Control Register
    uint8_t region; // Region
    uint8_t mreg; // Mapper Register, function depends on mapper
    uint8_t romslot[4]; // ROM Slots (Banks), 16K or 8K depending on mapper
    uint8_t cartram_enabled; // Cartridge RAM Enabled
} sms_sys_t;

void cega_sms_init(void);
void cega_sms_deinit(void);

void cega_sms_reset(void);

void cega_sms_set_bios(int);
void cega_sms_set_fmaudio(int);
void cega_sms_set_region(int);
void cega_sms_set_mapper(int);

int cega_sms_bios_load_file(const char*);

size_t cega_sms_state_size(void);

void cega_sms_state_load_raw(const void*);
int cega_sms_state_load(const char*);

const void* cega_sms_state_save_raw(void);
int cega_sms_state_save(const char*);

int cega_sms_sram_load(const char*);
int cega_sms_sram_save(const char*);

void cega_gg_init(void);
void cega_gg_set_smsmode(int);

#endif
