mirror of
https://github.com/libretro/RACE.git
synced 2024-11-23 08:59:49 +00:00
465 lines
12 KiB
C
465 lines
12 KiB
C
/*---------------------------------------------------------------------------
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version. See also the license.txt file for
|
|
* additional informations.
|
|
*---------------------------------------------------------------------------
|
|
*/
|
|
|
|
|
|
#ifndef _MEMORYH_
|
|
#define _MEMORYH_
|
|
|
|
#include <retro_inline.h>
|
|
#include "types.h"
|
|
#include "neopopsound.h"
|
|
#include "sound.h"
|
|
#include "input.h"
|
|
#include "graphics.h"
|
|
#include "main.h"
|
|
#include "flash.h"
|
|
|
|
#ifdef DRZ80
|
|
#include "DrZ80_support.h"
|
|
#else
|
|
#ifdef CZ80
|
|
#include "cz80_support.h"
|
|
#else
|
|
#include "z80.h"
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* Maximum ROM size is 4 megabytes */
|
|
#define MAINROM_SIZE_MAX (4*1024*1024)
|
|
|
|
extern unsigned char mainram[]; /* All RAM areas */
|
|
extern unsigned char mainrom[]; /* ROM image area */
|
|
extern unsigned char cpurom[]; /* Bios ROM image area */
|
|
#if 0
|
|
extern unsigned int cartAddrMask; /* Mask for reading/writing mainrom */
|
|
#endif
|
|
|
|
/* tlcs 900h memory */
|
|
#if 0
|
|
extern unsigned char cpuram[]; /* 900h cpu core needs this.. */
|
|
#endif
|
|
extern unsigned char *cpuram;
|
|
void mem_init(void);
|
|
|
|
#if 0
|
|
unsigned char *get_address(unsigned int addr);
|
|
unsigned char *get_addressW(unsigned int addr);
|
|
#endif
|
|
|
|
/* gameboy memory */
|
|
|
|
extern unsigned char (*gbMemReadB)(unsigned short addr);
|
|
extern void (*gbMemWriteB)(unsigned short addr, unsigned char data);
|
|
unsigned short gbMemReadW(unsigned short addr);
|
|
void gbMemWriteW(unsigned short addr, unsigned short data);
|
|
|
|
/* z80 memory functions */
|
|
|
|
extern unsigned char (*z80MemReadB)(unsigned short addr);
|
|
extern unsigned short (*z80MemReadW)(unsigned short addr);
|
|
extern void (*z80MemWriteB)(unsigned short addr, unsigned char data);
|
|
extern void (*z80MemWriteW)(unsigned short addr, unsigned short data);
|
|
extern void (*z80PortWriteB)(unsigned char port, unsigned char data);
|
|
extern unsigned char (*z80PortReadB)(unsigned char port);
|
|
|
|
#if defined(DRZ80) || defined(CZ80)
|
|
unsigned char z80ngpMemReadB(unsigned short addr);
|
|
unsigned short z80ngpMemReadW(unsigned short addr);
|
|
void DrZ80ngpMemWriteB(unsigned char data, unsigned short addr);
|
|
void DrZ80ngpMemWriteW(unsigned short data, unsigned short addr);
|
|
void DrZ80ngpPortWriteB(unsigned short port, unsigned char data);
|
|
unsigned char DrZ80ngpPortReadB(unsigned short port);
|
|
#endif
|
|
|
|
/* used internally by z80 emulation for emulation of the memory
|
|
* map of the Game Gear */
|
|
extern unsigned char *ggVRAM;
|
|
extern unsigned char *ggCRAM;
|
|
|
|
unsigned char z80ggMemReadB(unsigned short addr);
|
|
unsigned short z80ggMemReadW(unsigned short addr);
|
|
void z80ggMemWriteB(unsigned short addr, unsigned char data);
|
|
void z80ggMemWriteW(unsigned short addr, unsigned short data);
|
|
void z80ggPortWriteB(unsigned char port, unsigned char data);
|
|
unsigned char z80ggPortReadB(unsigned char port);
|
|
|
|
/* definitions for wdc6502 emulation */
|
|
extern unsigned char (*w65MemReadB)(unsigned short addr);
|
|
#if 0
|
|
extern unsigned short (*w65MemReadW)(unsigned short addr);
|
|
extern void (*w65MemWriteW)(unsigned short addr, unsigned short data);
|
|
#endif
|
|
unsigned short w65MemReadW(unsigned short addr);
|
|
extern void (*w65MemWriteB)(unsigned short addr, unsigned char data);
|
|
void w65MemWriteW(unsigned short addr, unsigned short data);
|
|
extern unsigned char *w65GetAddress(unsigned short addr);
|
|
|
|
//
|
|
// Supervision specific
|
|
//
|
|
extern unsigned char *svVRAM;
|
|
|
|
//
|
|
// HuC specific defines & externs
|
|
//
|
|
|
|
extern unsigned char hucMMR[8];
|
|
|
|
/*
|
|
* i8086 functions
|
|
*/
|
|
|
|
extern unsigned char *x86Ports;
|
|
|
|
unsigned char x86MemReadB(unsigned int addr);
|
|
void x86MemWriteB(unsigned int addr, unsigned char data);
|
|
unsigned short x86MemReadW(unsigned int addr);
|
|
void x86MemWriteW(unsigned int addr, unsigned short data);
|
|
unsigned char x86PortReadB(unsigned short port);
|
|
void x86PortWriteB(unsigned short port, unsigned char data);
|
|
unsigned short x86PortReadW(unsigned short port);
|
|
void x86PortWriteW(unsigned short port, unsigned short data);
|
|
|
|
/* used for Wonderswan graphics emulation */
|
|
|
|
extern unsigned char *wsTileMap0;
|
|
extern unsigned char *wsTileMap1;
|
|
extern unsigned char *wsPatterns;
|
|
extern unsigned char *wsSpriteTable;
|
|
|
|
/*
|
|
* i8048 functions
|
|
*/
|
|
|
|
extern unsigned char *advBios;
|
|
extern unsigned char *advVidRAM;
|
|
|
|
unsigned char i8048ROMReadB(unsigned int addr);
|
|
unsigned char i8048ExtReadB(unsigned int addr);
|
|
void i8048ExtWriteB(unsigned int addr, unsigned char data);
|
|
unsigned char i8048PortReadB(unsigned char port);
|
|
void i8048PortWriteB(unsigned char port, unsigned char data);
|
|
void i8048SetT1(void);
|
|
unsigned char i8048GetT1(void);
|
|
|
|
/*
|
|
* sm85xx memory functions
|
|
*/
|
|
|
|
extern unsigned char (*sm85MemReadB)(unsigned short addr);
|
|
extern void (*sm85MemWriteB)(unsigned short addr, unsigned char data);
|
|
|
|
extern unsigned char realBIOSloaded;
|
|
|
|
static INLINE unsigned char *get_address(unsigned int addr)
|
|
{
|
|
addr&= 0x00FFFFFF;
|
|
if (addr<0x00200000)
|
|
{
|
|
if (addr<0x000008a0)
|
|
{
|
|
#if 0
|
|
if(((unsigned int)&cpuram[addr] >> 24) == 0xFF)
|
|
dbg_print("1) addr=0x%X returning=0x%X\n", addr, &cpuram[addr]);
|
|
#endif
|
|
return &cpuram[addr];
|
|
}
|
|
if (addr>0x00003fff && addr<0x00018000)
|
|
{
|
|
#if 0
|
|
if((unsigned int)&mainram[addr-0x00004000] >> 24 == 0xFF)
|
|
dbg_print("2) addr=0x%X returning=0x%X\n", addr, &mainram[addr-0x00004000]);
|
|
#endif
|
|
|
|
switch (addr) /* Thanks Koyote */
|
|
{
|
|
case 0x6F80:
|
|
mainram[addr-0x00004000] = 0xFF;
|
|
break;
|
|
case 0x6F80+1:
|
|
mainram[addr-0x00004000] = 0x03;
|
|
break;
|
|
case 0x6F85:
|
|
mainram[addr-0x00004000] = 0x00;
|
|
break;
|
|
case 0x6F82:
|
|
mainram[addr-0x00004000] = ngpInputState;
|
|
break;
|
|
case 0x6DA2:
|
|
mainram[addr-0x00004000] = 0x80;
|
|
break;
|
|
}
|
|
return &mainram[addr-0x00004000];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (addr<0x00400000)
|
|
{
|
|
return &mainrom[(addr-0x00200000) /*&cartAddrMask*/];
|
|
}
|
|
if(addr<0x00800000) /* Flavor added */
|
|
{
|
|
return 0;
|
|
}
|
|
if (addr<0x00A00000)
|
|
{
|
|
return &mainrom[(addr-(0x00800000-0x00200000))/*&cartAddrMask*/];
|
|
}
|
|
if(addr<0x00FF0000) /* Flavor added */
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
#if 0
|
|
if((unsigned int)&cpurom[addr-0x00ff0000] >> 24 == 0xFF)
|
|
dbg_print("5) addr=0x%X returning=0x%X\n", addr, &cpurom[addr-0x00ff0000]);
|
|
#endif
|
|
|
|
return &cpurom[addr-0x00ff0000];
|
|
}
|
|
|
|
#if 0
|
|
dbg_print("6) addr=0x%X returning=0\n", addr);
|
|
#endif
|
|
return 0; /* Flavor ERROR */
|
|
}
|
|
|
|
/* read a byte from a memory address (addr) */
|
|
static INLINE unsigned char tlcsMemReadB(unsigned int addr)
|
|
{
|
|
addr&= 0x00FFFFFF;
|
|
|
|
if(currentCommand == COMMAND_INFO_READ)
|
|
return flashReadInfo(addr);
|
|
|
|
if (addr < 0x00200000) {
|
|
if (addr < 0x000008A0) {
|
|
if(addr == 0xBC)
|
|
{
|
|
ngpSoundExecute();
|
|
}
|
|
return cpuram[addr];
|
|
}
|
|
else if (addr > 0x00003FFF && addr < 0x00018000)
|
|
{
|
|
|
|
switch (addr) /* Thanks Koyote */
|
|
{
|
|
case 0x6DA2:
|
|
return 0x80;
|
|
break;
|
|
case 0x6F80:
|
|
return 0xFF;
|
|
break;
|
|
case 0x6F80+1:
|
|
return 0x03;
|
|
break;
|
|
case 0x6F85:
|
|
return 0x00;
|
|
break;
|
|
case 0x6F82:
|
|
return ngpInputState;
|
|
break;
|
|
|
|
default:
|
|
return mainram[addr-0x00004000];
|
|
}
|
|
return mainram[addr-0x00004000];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (addr<0x00400000)
|
|
return mainrom[(addr-0x00200000)/*&cartAddrMask*/];
|
|
if (addr<0x00800000)
|
|
return 0xFF;
|
|
if (addr<0x00a00000)
|
|
return mainrom[(addr-(0x00800000-0x00200000))/*&cartAddrMask*/];
|
|
if (addr<0x00ff0000)
|
|
return 0xFF;
|
|
return cpurom[addr-0x00ff0000];
|
|
}
|
|
return 0xFF;
|
|
}
|
|
|
|
/* read a word from a memory address (addr) */
|
|
static INLINE unsigned short tlcsMemReadW(unsigned int addr)
|
|
{
|
|
#ifdef TARGET_GP2X
|
|
register unsigned short i asm("r0");
|
|
register unsigned char *gA asm("r1");
|
|
|
|
gA = get_address(addr);
|
|
|
|
if(gA == 0)
|
|
return 0;
|
|
|
|
asm volatile(
|
|
"ldrb %0, [%1]\n\t"
|
|
"ldrb r2, [%1, #1]\n\t"
|
|
"orr %0, %0, r2, asl #8"
|
|
: "=r" (i)
|
|
: "r" (gA)
|
|
: "r2");
|
|
|
|
return i;
|
|
#else
|
|
/* unsigned short i;
|
|
unsigned char *gA = get_address(addr);
|
|
|
|
if(gA == 0)
|
|
return 0;
|
|
|
|
i = *(gA++);
|
|
i |= (*gA) << 8;
|
|
|
|
return i;
|
|
*/
|
|
return tlcsMemReadB(addr) | (tlcsMemReadB(addr+1) << 8);
|
|
#endif
|
|
}
|
|
|
|
/* read a long word from a memory address (addr) */
|
|
static INLINE unsigned int tlcsMemReadL(unsigned int addr)
|
|
{
|
|
#ifdef TARGET_GP2X
|
|
register unsigned int i asm("r0");
|
|
register unsigned char *gA asm("r4");
|
|
|
|
gA = get_address(addr);
|
|
|
|
if(gA == 0)
|
|
return 0;
|
|
|
|
asm volatile(
|
|
"bic r1,%1,#3 \n"
|
|
"ldmia r1,{r0,r3} \n"
|
|
"ands r1,%1,#3 \n"
|
|
"movne r2,r1,lsl #3 \n"
|
|
"movne r0,r0,lsr r2 \n"
|
|
"rsbne r1,r2,#32 \n"
|
|
"orrne r0,r0,r3,lsl r1"
|
|
: "=r"(i)
|
|
: "r"(gA)
|
|
: "r1","r2","r3");
|
|
|
|
return i;
|
|
#else
|
|
unsigned int i;
|
|
unsigned char *gA = get_address(addr);
|
|
|
|
if(gA == 0)
|
|
return 0;
|
|
|
|
i = *(gA++);
|
|
i |= (*(gA++)) << 8;
|
|
i |= (*(gA++)) << 16;
|
|
i |= (unsigned int)(*gA) << 24;
|
|
|
|
#if 0
|
|
return tlcsMemReadB(addr) | (tlcsMemReadB(addr +1) << 8) | (tlcsMemReadB(addr +2) << 16) | (tlcsMemReadB(addr +3) << 24);
|
|
#else
|
|
return i;
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
/* write a byte (data) to a memory address (addr) */
|
|
static INLINE void tlcsMemWriteB(unsigned int addr, unsigned char data)
|
|
{
|
|
addr&= 0x00FFFFFF;
|
|
if (addr<0x000008a0)
|
|
{
|
|
switch(addr) {
|
|
#if 0
|
|
case 0x80: /* CPU speed */
|
|
break;
|
|
#endif
|
|
case 0xA0: /* L CH Sound Source Control Register */
|
|
if (cpuram[0xB8] == 0x55 && cpuram[0xB9] == 0xAA)
|
|
Write_SoundChipNoise(data);/*Flavor SN76496Write(0, data); */
|
|
break;
|
|
case 0xA1: /* R CH Sound Source Control Register */
|
|
if (cpuram[0xB8] == 0x55 && cpuram[0xB9] == 0xAA)
|
|
Write_SoundChipTone(data); /*Flavor SN76496Write(0, data); */
|
|
break;
|
|
case 0xA2: /* L CH DAC Control Register */
|
|
ngpSoundExecute();
|
|
if (cpuram[0xB8] == 0xAA)
|
|
dac_writeL(data); /*Flavor DAC_data_w(0,data); */
|
|
break;
|
|
#if 0
|
|
case 0xA3: /* R CH DAC Control Register */ /* Flavor hack for mono only sound */
|
|
ngpSoundExecute();
|
|
if (cpuram[0xB8] == 0xAA)
|
|
dac_writeR(data); /* Flavor DAC_data_w(1,data); */
|
|
break;
|
|
#endif
|
|
case 0xB8: /* Z80 Reset */
|
|
#if 0
|
|
if (data == 0x55) DAC_data_w(0,0);
|
|
#endif
|
|
case 0xB9: /* Sourd Source Reset Control Register */
|
|
switch(data)
|
|
{
|
|
case 0x55:
|
|
ngpSoundStart();
|
|
break;
|
|
case 0xAA:
|
|
ngpSoundExecute();
|
|
ngpSoundOff();
|
|
break;
|
|
}
|
|
break;
|
|
case 0xBA:
|
|
ngpSoundExecute();
|
|
#if defined(DRZ80) || defined(CZ80)
|
|
Z80_Cause_Interrupt(Z80_NMI_INT);
|
|
#else
|
|
z80Interrupt(Z80NMI);
|
|
#endif
|
|
break;
|
|
}
|
|
cpuram[addr] = data;
|
|
return;
|
|
}
|
|
else if (addr>0x00003fff && addr<0x00018000)
|
|
{
|
|
if (addr == 0x87E2 && mainram[0x47F0] != 0xAA)
|
|
return; /* disallow writes to GEMODE */
|
|
|
|
#if 0
|
|
if((addr >= 0x8800 && addr <= 0x88FF)
|
|
|| (addr >= 0x8C00 && addr <= 0x8FFF)
|
|
|| (addr >= 0xA000 && addr <= 0xBFFF)
|
|
|| addr == 0x00008020
|
|
|| addr == 0x00008021)
|
|
spritesDirty = true;
|
|
#endif
|
|
|
|
mainram[addr-0x00004000] = data;
|
|
return;
|
|
}
|
|
else if (addr>=0x00200000 && addr<0x00400000)
|
|
flashChipWrite(addr, data);
|
|
else if (addr>=0x00800000 && addr<0x00A00000)
|
|
flashChipWrite(addr, data);
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* _MEMORYH_ */
|