main sega_mapper.c
  1#include "genesis.h"
  2
  3uint16_t read_sram_w(uint32_t address, m68k_context * context)
  4{
  5	genesis_context * gen = context->system;
  6	address &= gen->save_ram_mask;
  7	switch(gen->save_type)
  8	{
  9	case RAM_FLAG_BOTH:
 10		return gen->save_storage[address] << 8 | gen->save_storage[address+1];
 11	case RAM_FLAG_EVEN:
 12		return gen->save_storage[address >> 1] << 8 | 0xFF;
 13	case RAM_FLAG_ODD:
 14		return gen->save_storage[address >> 1] | 0xFF00;
 15	}
 16	return 0xFFFF;//We should never get here
 17}
 18
 19uint8_t read_sram_b(uint32_t address, m68k_context * context)
 20{
 21	genesis_context * gen = context->system;
 22	address &= gen->save_ram_mask;
 23	switch(gen->save_type)
 24	{
 25	case RAM_FLAG_BOTH:
 26		return gen->save_storage[address];
 27	case RAM_FLAG_EVEN:
 28		if (address & 1) {
 29			return 0xFF;
 30		} else {
 31			return gen->save_storage[address >> 1];
 32		}
 33	case RAM_FLAG_ODD:
 34		if (address & 1) {
 35			return gen->save_storage[address >> 1];
 36		} else {
 37			return 0xFF;
 38		}
 39	}
 40	return 0xFF;//We should never get here
 41}
 42
 43m68k_context * write_sram_area_w(uint32_t address, m68k_context * context, uint16_t value)
 44{
 45	genesis_context * gen = context->system;
 46	if ((gen->bank_regs[0] & 0x3) == 1) {
 47		address &= gen->save_ram_mask;
 48		switch(gen->save_type)
 49		{
 50		case RAM_FLAG_BOTH:
 51			gen->save_storage[address] = value >> 8;
 52			gen->save_storage[address+1] = value;
 53			break;
 54		case RAM_FLAG_EVEN:
 55			gen->save_storage[address >> 1] = value >> 8;
 56			break;
 57		case RAM_FLAG_ODD:
 58			gen->save_storage[address >> 1] = value;
 59			break;
 60		}
 61	}
 62	return context;
 63}
 64
 65m68k_context * write_sram_area_b(uint32_t address, m68k_context * context, uint8_t value)
 66{
 67	genesis_context * gen = context->system;
 68	if ((gen->bank_regs[0] & 0x3) == 1) {
 69		address &= gen->save_ram_mask;
 70		switch(gen->save_type)
 71		{
 72		case RAM_FLAG_BOTH:
 73			gen->save_storage[address] = value;
 74			break;
 75		case RAM_FLAG_EVEN:
 76			if (!(address & 1)) {
 77				gen->save_storage[address >> 1] = value;
 78			}
 79			break;
 80		case RAM_FLAG_ODD:
 81			if (address & 1) {
 82				gen->save_storage[address >> 1] = value;
 83			}
 84			break;
 85		}
 86	}
 87	return context;
 88}
 89
 90m68k_context * write_bank_reg_w(uint32_t address, m68k_context * context, uint16_t value)
 91{
 92	genesis_context * gen = context->system;
 93	address &= 0xE;
 94	address >>= 1;
 95	gen->bank_regs[address] = value;
 96	if (!address) {
 97		if (value & 1) {
 98			//Used for games that only use the mapper for SRAM
 99			if (context->mem_pointers[gen->mapper_start_index]) {
100				gen->mapper_temp = context->mem_pointers[gen->mapper_start_index];
101			}
102			context->mem_pointers[gen->mapper_start_index] = NULL;
103			//For games that need more than 4MB
104			for (int i = 4; i < 8; i++)
105			{
106				context->mem_pointers[gen->mapper_start_index + i] = NULL;
107			}
108		} else {
109			//Used for games that only use the mapper for SRAM
110			if (!context->mem_pointers[gen->mapper_start_index]) {
111				context->mem_pointers[gen->mapper_start_index] = gen->mapper_temp;
112			}
113			//For games that need more than 4MB
114			for (int i = 4; i < 8; i++)
115			{
116				context->mem_pointers[gen->mapper_start_index + i] = gen->cart + 0x40000*gen->bank_regs[i];
117			}
118		}
119	} else {
120		void *new_ptr = gen->cart + 0x40000*value;
121		if (context->mem_pointers[gen->mapper_start_index + address] != new_ptr) {
122			m68k_invalidate_code_range(gen->m68k, address * 0x80000, (address + 1) * 0x80000);
123			context->mem_pointers[gen->mapper_start_index + address] = new_ptr;
124		}
125	}
126	return context;
127}
128
129m68k_context * write_bank_reg_b(uint32_t address, m68k_context * context, uint8_t value)
130{
131	if (address & 1) {
132		write_bank_reg_w(address, context, value);
133	}
134	return context;
135}
136
137void sega_mapper_serialize(genesis_context *gen, serialize_buffer *buf)
138{
139	save_buffer8(buf, gen->bank_regs, sizeof(gen->bank_regs));
140}
141
142void sega_mapper_deserialize(deserialize_buffer *buf, genesis_context *gen)
143{
144	for (int i = 0; i < sizeof(gen->bank_regs); i++)
145	{
146		write_bank_reg_w(i * 2, gen->m68k, load_int8(buf));
147	}
148}