mirror of
https://github.com/libretro/Mu.git
synced 2026-05-06 20:34:20 +00:00
Major chipselect overhaul
Does not compile yet
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "memoryAccess.h"//for size macros
|
||||
#include "emuFeatureRegistersSpec.h"
|
||||
|
||||
//emu errors
|
||||
@@ -37,16 +38,6 @@ enum{
|
||||
CARD_MMC
|
||||
};
|
||||
|
||||
//memory banks
|
||||
enum{
|
||||
EMPTY_BANK = 0,
|
||||
RAM_BANK,
|
||||
ROM_BANK,
|
||||
REG_BANK,
|
||||
SED1376_REG_BANK,
|
||||
SED1376_FB_BANK
|
||||
};
|
||||
|
||||
//types
|
||||
typedef struct{
|
||||
bool buttonUp;
|
||||
@@ -96,28 +87,6 @@ typedef struct{
|
||||
#define CRYSTAL_FREQUENCY 32768.0
|
||||
#define CPU_FREQUENCY (palmCrystalCycles * CRYSTAL_FREQUENCY)
|
||||
|
||||
//address space
|
||||
#define NUM_BANKS(areaSize) (areaSize & 0x0000FFFF ? (areaSize >> 16) + 1 : areaSize >> 16)
|
||||
#define START_BANK(address) (address >> 16)
|
||||
#define END_BANK(address, size) (START_BANK(address) + NUM_BANKS(size) - 1)
|
||||
#define BANK_IN_RANGE(bank, address, size) (bank >= START_BANK(address) && bank <= END_BANK(address, size))
|
||||
#define TOTAL_MEMORY_BANKS 0x10000
|
||||
|
||||
//memory chip addresses
|
||||
#define RAM_START_ADDRESS 0x00000000
|
||||
#define ROM_START_ADDRESS 0x10000000
|
||||
#define REG_START_ADDRESS 0xFFFFF000
|
||||
#define RAM_SIZE (16 * 0x100000)//16mb RAM
|
||||
#define ROM_SIZE (4 * 0x100000)//4mb ROM
|
||||
#define REG_SIZE 0xE00
|
||||
#define BOOTLOADER_SIZE 0x200
|
||||
|
||||
//display chip addresses
|
||||
#define SED1376_REG_START_ADDRESS 0x1FF80000
|
||||
#define SED1376_FB_START_ADDRESS 0x1FFA0000
|
||||
#define SED1376_REG_SIZE 0xB4//it has 0x20000 used address space entrys but only 0xB4 registers
|
||||
#define SED1376_FB_SIZE 0x20000//0x14000 in size, likely also has 0x20000 used address space entrys, using 0x20000 to prevent speed penalty of checking validity on every access
|
||||
|
||||
//config options
|
||||
#define EMU_FPS 60.0
|
||||
#define SDCARD_STATE_CHUNKS_VECTOR_SIZE 100
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "m68k/m68k.h"
|
||||
|
||||
|
||||
chip_t chips[4];
|
||||
int32_t pllWakeWait;
|
||||
uint32_t clk32Counter;
|
||||
double timer1CycleCounter;
|
||||
@@ -64,6 +65,133 @@ static inline bool pllOn(){
|
||||
return (registerArrayRead16(PLLCR) & 0x0008) == 0;
|
||||
}
|
||||
|
||||
static inline void setCsa(uint16_t value){
|
||||
chips[CHIP_A_ROM].enable = CAST_TO_BOOL(value & 0x0001);
|
||||
chips[CHIP_A_ROM].readOnly = CAST_TO_BOOL(value & 0x8000);
|
||||
chips[CHIP_A_ROM].size = 0x20000/*128kb*/ << ((value >> 1) & 0x0007);
|
||||
|
||||
registerArrayWrite16(CSA, value & 0x81FF);
|
||||
}
|
||||
|
||||
static inline void setCsb(uint16_t value){
|
||||
uint16_t csControl1 = registerArrayRead16(CSCTRL1);
|
||||
|
||||
chips[CHIP_B_SED].enable = CAST_TO_BOOL(value & 0x0001);
|
||||
chips[CHIP_B_SED].readOnly = CAST_TO_BOOL(value & 0x8000);
|
||||
chips[CHIP_B_SED].size = 0x20000/*128kb*/ << ((value >> 1) & 0x0007);
|
||||
|
||||
//attributes
|
||||
chips[CHIP_B_SED].supervisorOnlyProtectedMemory = CAST_TO_BOOL(value & 0x4000);
|
||||
chips[CHIP_B_SED].readOnlyForProtectedMemory = CAST_TO_BOOL(value & 0x2000);
|
||||
if(csControl1 & 0x4000 && csControl1 & 0x0001)
|
||||
chips[CHIP_B_SED].unprotectedSize = 0x8000/*32kb*/ << (((value >> 11) & 0x0003) | 0x0004);
|
||||
else
|
||||
chips[CHIP_B_SED].unprotectedSize = 0x8000/*32kb*/ << ((value >> 11) & 0x0003);
|
||||
|
||||
registerArrayWrite16(CSB, value & 0xF9FF);
|
||||
}
|
||||
|
||||
static inline void setCsc(uint16_t value){
|
||||
uint16_t csControl1 = registerArrayRead16(CSCTRL1);
|
||||
|
||||
chips[CHIP_C_USB].enable = CAST_TO_BOOL(value & 0x0001);
|
||||
chips[CHIP_C_USB].readOnly = CAST_TO_BOOL(value & 0x8000);
|
||||
chips[CHIP_C_USB].size = 0x8000/*32kb*/ << ((value >> 1) & 0x0007);
|
||||
|
||||
//attributes
|
||||
chips[CHIP_C_USB].supervisorOnlyProtectedMemory = CAST_TO_BOOL(value & 0x4000);
|
||||
chips[CHIP_C_USB].readOnlyForProtectedMemory = CAST_TO_BOOL(value & 0x2000);
|
||||
if(csControl1 & 0x4000 && csControl1 & 0x0004)
|
||||
chips[CHIP_C_USB].unprotectedSize = 0x8000/*32kb*/ << (((value >> 11) & 0x0003) | 0x0004);
|
||||
else
|
||||
chips[CHIP_C_USB].unprotectedSize = 0x8000/*32kb*/ << ((value >> 11) & 0x0003);
|
||||
|
||||
registerArrayWrite16(CSC, value & 0xF9FF);
|
||||
}
|
||||
|
||||
static inline void setCsd(uint16_t value){
|
||||
uint16_t csControl1 = registerArrayRead16(CSCTRL1);
|
||||
|
||||
chips[CHIP_D_RAM].enable = CAST_TO_BOOL(value & 0x0001);
|
||||
chips[CHIP_D_RAM].readOnly = CAST_TO_BOOL(value & 0x8000);
|
||||
if(csControl1 & 0x0040 && value & 0x0200)
|
||||
chips[CHIP_D_RAM].size = 0x800000/*8mb*/ << ((value >> 1) & 0x0001);
|
||||
else
|
||||
chips[CHIP_D_RAM].size = 0x8000/*32kb*/ << ((value >> 1) & 0x0007);
|
||||
|
||||
//attributes
|
||||
chips[CHIP_D_RAM].supervisorOnlyProtectedMemory = CAST_TO_BOOL(value & 0x4000);
|
||||
chips[CHIP_D_RAM].readOnlyForProtectedMemory = CAST_TO_BOOL(value & 0x2000);
|
||||
if(csControl1 & 0x4000 && csControl1 & 0x0010)
|
||||
chips[CHIP_D_RAM].unprotectedSize = 0x8000/*32kb*/ << (((value >> 11) & 0x0003) | 0x0004);
|
||||
else
|
||||
chips[CHIP_D_RAM].unprotectedSize = 0x8000/*32kb*/ << ((value >> 11) & 0x0003);
|
||||
|
||||
registerArrayWrite16(CSD, value);
|
||||
}
|
||||
|
||||
static inline void setCsgba(uint16_t value){
|
||||
uint16_t csugba = registerArrayRead16(CSUGBA);
|
||||
|
||||
//add extra address bits if enabled
|
||||
if(csugba & 0x8000)
|
||||
chips[CHIP_A_ROM].start = ((csugba >> 12) & 0x0007) << 29 | (value >> 1) << 13;
|
||||
else
|
||||
chips[CHIP_A_ROM].start = (value >> 1) << 13;
|
||||
|
||||
registerArrayWrite16(CSGBA, value & 0xFFFE);
|
||||
}
|
||||
|
||||
static inline void setCsgbb(uint16_t value){
|
||||
uint16_t csugba = registerArrayRead16(CSUGBA);
|
||||
|
||||
//add extra address bits if enabled
|
||||
if(csugba & 0x8000)
|
||||
chips[CHIP_B_SED].start = ((csugba >> 8) & 0x0007) << 29 | (value >> 1) << 13;
|
||||
else
|
||||
chips[CHIP_B_SED].start = (value >> 1) << 13;
|
||||
|
||||
registerArrayWrite16(CSGBB, value & 0xFFFE);
|
||||
}
|
||||
|
||||
static inline void setCsgbc(uint16_t value){
|
||||
uint16_t csugba = registerArrayRead16(CSUGBA);
|
||||
|
||||
//add extra address bits if enabled
|
||||
if(csugba & 0x8000)
|
||||
chips[CHIP_C_USB].start = ((csugba >> 4) & 0x0007) << 29 | (value >> 1) << 13;
|
||||
else
|
||||
chips[CHIP_C_USB].start = (value >> 1) << 13;
|
||||
|
||||
registerArrayWrite16(CSGBC, value & 0xFFFE);
|
||||
}
|
||||
|
||||
static inline void setCsgbd(uint16_t value){
|
||||
uint16_t csugba = registerArrayRead16(CSUGBA);
|
||||
|
||||
//add extra address bits if enabled
|
||||
if(csugba & 0x8000)
|
||||
chips[CHIP_D_RAM].start = (csugba & 0x0007) << 29 | (value >> 1) << 13;
|
||||
else
|
||||
chips[CHIP_D_RAM].start = (value >> 1) << 13;
|
||||
|
||||
registerArrayWrite16(CSGBD, value & 0xFFFE);
|
||||
}
|
||||
|
||||
static inline void setCsctrl1(uint16_t value){
|
||||
uint16_t oldCsctrl1 = registerArrayRead16(CSCTRL1);
|
||||
|
||||
registerArrayWrite16(CSCTRL1, value & 0x7F55);
|
||||
if((oldCsctrl1 & 0x4055) != (value & 0x4055)){
|
||||
//something important changed, update all chipselects
|
||||
//CSA is not dependant on CSCTRL1
|
||||
setCsb(registerArrayRead16(CSB));
|
||||
setCsc(registerArrayRead16(CSC));
|
||||
setCsd(registerArrayRead16(CSD));
|
||||
}
|
||||
}
|
||||
//csctrl 2 and 3 only deal with timing and bus transfer size
|
||||
|
||||
|
||||
void printUnknownHwAccess(unsigned int address, unsigned int value, unsigned int size, bool isWrite){
|
||||
if(isWrite){
|
||||
@@ -358,9 +486,17 @@ static inline void setPllcr(uint16_t value){
|
||||
|
||||
static inline void setScr(uint8_t value){
|
||||
uint8_t oldScr = registerArrayRead8(SCR);
|
||||
registerArrayWrite8(SCR, value);
|
||||
if((value & 0x04) != (oldScr & 0x04)){
|
||||
if(value & 0x04)
|
||||
uint8_t newScr = value;
|
||||
|
||||
//preserve privilege violation, write protect violation and bus error timeout
|
||||
newScr |= oldScr & 0xE0;
|
||||
|
||||
//clear violations on writing 1 to them
|
||||
newScr &= ~(oldScr & value & 0xE0);
|
||||
|
||||
registerArrayWrite8(SCR, newScr);//must be written before calling setRegisterFFFFAccessMode
|
||||
if((newScr & 0x04) != (oldScr & 0x04)){
|
||||
if(newScr & 0x04)
|
||||
setRegisterXXFFAccessMode();
|
||||
else
|
||||
setRegisterFFFFAccessMode();
|
||||
@@ -1019,33 +1155,66 @@ void setHwRegister16(unsigned int address, unsigned int value){
|
||||
//missing bits 13, 9, 8 and 7
|
||||
registerArrayWrite16(address, value & 0xDC7F);
|
||||
break;
|
||||
|
||||
/*
|
||||
|
||||
case CSA:
|
||||
setCsa(value);
|
||||
refreshBankHandlers();
|
||||
break;
|
||||
|
||||
case CSB:
|
||||
setCsb(value);
|
||||
refreshBankHandlers();
|
||||
break;
|
||||
|
||||
case CSC:
|
||||
setCsc(value);
|
||||
refreshBankHandlers();
|
||||
break;
|
||||
|
||||
case CSD:
|
||||
setCsd(value);
|
||||
refreshBankHandlers();
|
||||
break;
|
||||
|
||||
case CSGBA:
|
||||
//unemulated
|
||||
//sets the starting location of ROM
|
||||
registerArrayWrite16(address, value & 0xFFFE);
|
||||
//sets the starting location of ROM(0x10000000)
|
||||
setCsgba(value);
|
||||
refreshBankHandlers();
|
||||
break;
|
||||
|
||||
|
||||
case CSGBB:
|
||||
//unemulated
|
||||
//sets the starting location of the SED1376
|
||||
registerArrayWrite16(address, value & 0xFFFE);
|
||||
//sets the starting location of the SED1376(0x1FF80000)
|
||||
setCsgbb(value);
|
||||
refreshBankHandlers();
|
||||
break;
|
||||
|
||||
|
||||
case CSGBC:
|
||||
//unemulated
|
||||
//sets the starting location of USBPhilipsPDIUSBD12(address 0x10400000)
|
||||
//since I dont plan on adding hotsync should be fine to leave unemulated, its unemulated in pose
|
||||
registerArrayWrite16(address, value & 0xFFFE);
|
||||
setCsgbc(value);
|
||||
refreshBankHandlers();
|
||||
break;
|
||||
|
||||
|
||||
case CSGBD:
|
||||
//unemulated
|
||||
//sets the starting location of RAM
|
||||
registerArrayWrite16(address, value & 0xFFFE);
|
||||
//sets the starting location of RAM(0x00000000)
|
||||
setCsgbd(value);
|
||||
refreshBankHandlers();
|
||||
break;
|
||||
|
||||
case CSUGBA:
|
||||
registerArrayWrite16(CSUGBA, value);
|
||||
//refresh all chipselect address lines
|
||||
setCsgba(registerArrayRead16(CSGBA));
|
||||
setCsgbb(registerArrayRead16(CSGBB));
|
||||
setCsgbc(registerArrayRead16(CSGBC));
|
||||
setCsgbd(registerArrayRead16(CSGBD));
|
||||
refreshBankHandlers();
|
||||
break;
|
||||
|
||||
case CSCTRL1:
|
||||
setCsctrl1(value);
|
||||
refreshBankHandlers();
|
||||
break;
|
||||
*/
|
||||
|
||||
default:
|
||||
printUnknownHwAccess(address, value, 16, true);
|
||||
@@ -1104,6 +1273,22 @@ void resetHwRegisters(){
|
||||
pllWakeWait = -1;
|
||||
timer1CycleCounter = 0.0;
|
||||
timer2CycleCounter = 0.0;
|
||||
for(uint32_t chip = CHIP_BEGIN; chip < CHIP_END; chip++){
|
||||
chips[chip].enable = false;
|
||||
chips[chip].start = 0x00000000;
|
||||
chips[chip].size = 0x00000000;
|
||||
chips[chip].mask = 0x00000000;
|
||||
|
||||
chips[chip].readOnly = false;
|
||||
chips[chip].readOnlyForProtectedMemory = false;
|
||||
chips[chip].supervisorOnlyProtectedMemory = false;
|
||||
chips[chip].unprotectedSize = 0x00000000;
|
||||
}
|
||||
//all chipselects are disabled at boot and CSA is mapped to 0x00000000 and covers the entire address range until CSGBA set otherwise
|
||||
chips[CHIP_A_ROM].enable = true;
|
||||
chips[CHIP_A_ROM].start = 0x00000000;
|
||||
chips[CHIP_A_ROM].size = 0xFFFFFFFF;
|
||||
chips[CHIP_A_ROM].mask = 0xFFFFFFFF;
|
||||
|
||||
//system control
|
||||
registerArrayWrite8(SCR, 0x1C);
|
||||
|
||||
@@ -28,7 +28,32 @@
|
||||
#define INT_TMR1 0x00000002 //level 6
|
||||
#define INT_SPI2 0x00000001 //level 4
|
||||
|
||||
//chip names
|
||||
enum{
|
||||
CHIP_BEGIN = 0,
|
||||
CHIP_A_ROM = 0,
|
||||
CHIP_B_SED,
|
||||
CHIP_C_USB,
|
||||
CHIP_D_RAM,
|
||||
CHIP_END
|
||||
};
|
||||
|
||||
//types
|
||||
typedef struct{
|
||||
bool enable;
|
||||
uint32_t start;
|
||||
uint32_t size;
|
||||
uint32_t mask;//the address lines the chip responds to, so 0x10000 on an chip with 16 address lines will return the value at 0x0000
|
||||
|
||||
//attributes
|
||||
bool readOnly;
|
||||
bool readOnlyForProtectedMemory;
|
||||
bool supervisorOnlyProtectedMemory;
|
||||
uint32_t unprotectedSize;
|
||||
}chip_t;
|
||||
|
||||
//variables
|
||||
extern chip_t chips[4];
|
||||
extern int32_t pllWakeWait;
|
||||
extern uint32_t clk32Counter;
|
||||
extern double timer1CycleCounter;
|
||||
|
||||
@@ -10,30 +10,30 @@
|
||||
static memory_access_t bankAccessors[TOTAL_MEMORY_BANKS];//these are not part of savestates because function pointers change with -fPIC
|
||||
uint8_t bankType[TOTAL_MEMORY_BANKS];//these go in savestates
|
||||
|
||||
//used for unmapped address space and writes to ROM
|
||||
//used for unmapped address space and writes to ROM, should trigger access exceptions if enabled
|
||||
static unsigned int unmappedRead(unsigned int address){return 0x00000000;}
|
||||
static void unmappedWrite(unsigned int address, unsigned int value){}
|
||||
|
||||
//RAM accesses
|
||||
static unsigned int ramRead8(unsigned int address){return BUFFER_READ_8(palmRam, address, RAM_START_ADDRESS);}
|
||||
static unsigned int ramRead16(unsigned int address){return BUFFER_READ_16(palmRam, address, RAM_START_ADDRESS);}
|
||||
static unsigned int ramRead32(unsigned int address){return BUFFER_READ_32(palmRam, address, RAM_START_ADDRESS);}
|
||||
static void ramWrite8(unsigned int address, unsigned int value){BUFFER_WRITE_8(palmRam, address, RAM_START_ADDRESS, value);}
|
||||
static void ramWrite16(unsigned int address, unsigned int value){BUFFER_WRITE_16(palmRam, address, RAM_START_ADDRESS, value);}
|
||||
static void ramWrite32(unsigned int address, unsigned int value){BUFFER_WRITE_32(palmRam, address, RAM_START_ADDRESS, value);}
|
||||
static unsigned int ramRead8(unsigned int address){return BUFFER_READ_8(palmRam, address, chips[CHIP_D_RAM].start);}
|
||||
static unsigned int ramRead16(unsigned int address){return BUFFER_READ_16(palmRam, address, chips[CHIP_D_RAM].start);}
|
||||
static unsigned int ramRead32(unsigned int address){return BUFFER_READ_32(palmRam, address, chips[CHIP_D_RAM].start);}
|
||||
static void ramWrite8(unsigned int address, unsigned int value){BUFFER_WRITE_8(palmRam, address, chips[CHIP_D_RAM].start, value);}
|
||||
static void ramWrite16(unsigned int address, unsigned int value){BUFFER_WRITE_16(palmRam, address, chips[CHIP_D_RAM].start, value);}
|
||||
static void ramWrite32(unsigned int address, unsigned int value){BUFFER_WRITE_32(palmRam, address, chips[CHIP_D_RAM].start, value);}
|
||||
|
||||
//ROM accesses
|
||||
static unsigned int romRead8(unsigned int address){return BUFFER_READ_8(palmRom, address, ROM_START_ADDRESS);}
|
||||
static unsigned int romRead16(unsigned int address){return BUFFER_READ_16(palmRom, address, ROM_START_ADDRESS);}
|
||||
static unsigned int romRead32(unsigned int address){return BUFFER_READ_32(palmRom, address, ROM_START_ADDRESS);}
|
||||
static unsigned int romRead8(unsigned int address){return BUFFER_READ_8(palmRom, address, chips[CHIP_A_ROM].start);}
|
||||
static unsigned int romRead16(unsigned int address){return BUFFER_READ_16(palmRom, address, chips[CHIP_A_ROM].start);}
|
||||
static unsigned int romRead32(unsigned int address){return BUFFER_READ_32(palmRom, address, chips[CHIP_A_ROM].start);}
|
||||
|
||||
//SED1376 framebuffer
|
||||
static unsigned int sed1376FramebufferRead8(unsigned int address){return BUFFER_READ_8(sed1376Framebuffer, address, SED1376_FB_START_ADDRESS);}
|
||||
static unsigned int sed1376FramebufferRead16(unsigned int address){return BUFFER_READ_16(sed1376Framebuffer, address, SED1376_FB_START_ADDRESS);}
|
||||
static unsigned int sed1376FramebufferRead32(unsigned int address){return BUFFER_READ_32(sed1376Framebuffer, address, SED1376_FB_START_ADDRESS);}
|
||||
static void sed1376FramebufferWrite8(unsigned int address, unsigned int value){BUFFER_WRITE_8(sed1376Framebuffer, address, SED1376_FB_START_ADDRESS, value);}
|
||||
static void sed1376FramebufferWrite16(unsigned int address, unsigned int value){BUFFER_WRITE_16(sed1376Framebuffer, address, SED1376_FB_START_ADDRESS, value);}
|
||||
static void sed1376FramebufferWrite32(unsigned int address, unsigned int value){BUFFER_WRITE_32(sed1376Framebuffer, address, SED1376_FB_START_ADDRESS, value);}
|
||||
static unsigned int sed1376FramebufferRead8(unsigned int address){return BUFFER_READ_8(sed1376Framebuffer, address, chips[CHIP_B_SED].start + SED1376_REG_SIZE);}
|
||||
static unsigned int sed1376FramebufferRead16(unsigned int address){return BUFFER_READ_16(sed1376Framebuffer, address, chips[CHIP_B_SED].start + SED1376_REG_SIZE);}
|
||||
static unsigned int sed1376FramebufferRead32(unsigned int address){return BUFFER_READ_32(sed1376Framebuffer, address, chips[CHIP_B_SED].start + SED1376_REG_SIZE);}
|
||||
static void sed1376FramebufferWrite8(unsigned int address, unsigned int value){BUFFER_WRITE_8(sed1376Framebuffer, address, chips[CHIP_B_SED].start + SED1376_REG_SIZE, value);}
|
||||
static void sed1376FramebufferWrite16(unsigned int address, unsigned int value){BUFFER_WRITE_16(sed1376Framebuffer, address, chips[CHIP_B_SED].start + SED1376_REG_SIZE, value);}
|
||||
static void sed1376FramebufferWrite32(unsigned int address, unsigned int value){BUFFER_WRITE_32(sed1376Framebuffer, address, chips[CHIP_B_SED].start + SED1376_REG_SIZE, value);}
|
||||
|
||||
|
||||
/* Read from anywhere */
|
||||
@@ -58,8 +58,6 @@ unsigned int m68k_read_disassembler_32(unsigned int address){return m68k_read_me
|
||||
|
||||
|
||||
static uint8_t getProperBankType(uint16_t bank){
|
||||
//RAM bank 0x0000 not correct, inaccurate but works fine
|
||||
|
||||
//special conditions
|
||||
if((bank & 0x00FF) == 0x00FF && registersAreXXFFMapped()){
|
||||
//XXFF register mode
|
||||
@@ -67,23 +65,21 @@ static uint8_t getProperBankType(uint16_t bank){
|
||||
}
|
||||
|
||||
//normal banks
|
||||
if(BANK_IN_RANGE(bank, RAM_START_ADDRESS, RAM_SIZE)){
|
||||
if(BANK_IN_RANGE(bank, chips[CHIP_D_RAM].start, chips[CHIP_D_RAM].size)){
|
||||
return RAM_BANK;
|
||||
}
|
||||
else if(BANK_IN_RANGE(bank, ROM_START_ADDRESS, ROM_SIZE)){
|
||||
else if(BANK_IN_RANGE(bank, chips[CHIP_A_ROM].start, chips[CHIP_A_ROM].size)){
|
||||
return ROM_BANK;
|
||||
}
|
||||
else if(BANK_IN_RANGE(bank, REG_START_ADDRESS, REG_SIZE)){
|
||||
return REG_BANK;
|
||||
}
|
||||
else if(BANK_IN_RANGE(bank, SED1376_REG_START_ADDRESS, SED1376_REG_SIZE) && sed1376ClockConnected()){
|
||||
return SED1376_REG_BANK;
|
||||
}
|
||||
else if(BANK_IN_RANGE(bank, SED1376_FB_START_ADDRESS, SED1376_FB_SIZE) && sed1376ClockConnected()){
|
||||
else if(BANK_IN_RANGE(bank, chips[CHIP_B_SED].start, chips[CHIP_B_SED].size) && sed1376ClockConnected()){
|
||||
if(bank - START_BANK(chips[CHIP_B_SED].start) < NUM_BANKS(SED1376_REG_SIZE))
|
||||
return SED1376_REG_BANK;
|
||||
return SED1376_FB_BANK;
|
||||
}
|
||||
|
||||
|
||||
return EMPTY_BANK;
|
||||
}
|
||||
|
||||
@@ -163,18 +159,15 @@ void setRegisterFFFFAccessMode(){
|
||||
|
||||
void setSed1376Attached(bool attached){
|
||||
if(attached){
|
||||
for(uint32_t bank = START_BANK(SED1376_REG_START_ADDRESS); bank < END_BANK(SED1376_REG_START_ADDRESS, SED1376_REG_SIZE); bank++){
|
||||
setBankType(bank, SED1376_REG_BANK);
|
||||
}
|
||||
for(uint32_t bank = START_BANK(SED1376_FB_START_ADDRESS); bank < END_BANK(SED1376_FB_START_ADDRESS, SED1376_FB_SIZE); bank++){
|
||||
setBankType(bank, SED1376_FB_BANK);
|
||||
for(uint32_t bank = START_BANK(chips[CHIP_B_SED].start); bank < END_BANK(chips[CHIP_B_SED].start, chips[CHIP_B_SED].size); bank++){
|
||||
if(bank - START_BANK(chips[CHIP_B_SED].start) < NUM_BANKS(SED1376_REG_SIZE))
|
||||
setBankType(bank, SED1376_REG_BANK);
|
||||
else
|
||||
setBankType(bank, SED1376_FB_BANK);
|
||||
}
|
||||
}
|
||||
else{
|
||||
for(uint32_t bank = START_BANK(SED1376_REG_START_ADDRESS); bank < END_BANK(SED1376_REG_START_ADDRESS, SED1376_REG_SIZE); bank++){
|
||||
setBankType(bank, EMPTY_BANK);
|
||||
}
|
||||
for(uint32_t bank = START_BANK(SED1376_FB_START_ADDRESS); bank < END_BANK(SED1376_FB_START_ADDRESS, SED1376_FB_SIZE); bank++){
|
||||
for(uint32_t bank = START_BANK(chips[CHIP_B_SED].start); bank < END_BANK(chips[CHIP_B_SED].start, chips[CHIP_B_SED].size); bank++){
|
||||
setBankType(bank, EMPTY_BANK);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,28 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
//address space
|
||||
#define NUM_BANKS(areaSize) (areaSize & 0x0000FFFF ? (areaSize >> 16) + 1 : areaSize >> 16)
|
||||
#define START_BANK(address) (address >> 16)
|
||||
#define END_BANK(address, size) (START_BANK(address) + NUM_BANKS(size) - 1)
|
||||
#define BANK_IN_RANGE(bank, address, size) (bank >= START_BANK(address) && bank <= END_BANK(address, size))
|
||||
#define TOTAL_MEMORY_BANKS 0x10000
|
||||
|
||||
//memory chip addresses
|
||||
//#define RAM_START_ADDRESS 0x00000000
|
||||
//#define ROM_START_ADDRESS 0x10000000
|
||||
#define REG_START_ADDRESS 0xFFFFF000
|
||||
#define RAM_SIZE (16 * 0x100000)//16mb RAM
|
||||
#define ROM_SIZE (4 * 0x100000)//4mb ROM
|
||||
#define REG_SIZE 0xE00
|
||||
#define BOOTLOADER_SIZE 0x200
|
||||
|
||||
//display chip addresses
|
||||
//#define SED1376_REG_START_ADDRESS 0x1FF80000
|
||||
//#define SED1376_FB_START_ADDRESS 0x1FFA0000
|
||||
#define SED1376_REG_SIZE 0x20000//it has 0x20000 used address space entrys but only 0xB4 registers
|
||||
#define SED1376_FB_SIZE 0x20000//0x14000 in size, likely also has 0x20000 used address space entrys, using 0x20000 to prevent speed penalty of checking validity on every access
|
||||
|
||||
//the read/write stuff looks messy here but makes the memory access functions alot cleaner
|
||||
#define BUFFER_READ_8(segment, accessAddress, startAddress) segment[accessAddress - startAddress]
|
||||
#define BUFFER_READ_16(segment, accessAddress, startAddress) segment[accessAddress - startAddress] << 8 | segment[accessAddress - startAddress + 1]
|
||||
@@ -10,6 +32,18 @@
|
||||
#define BUFFER_WRITE_16(segment, accessAddress, startAddress, value) segment[accessAddress - startAddress] = value >> 8; segment[accessAddress - startAddress + 1] = value & 0xFF
|
||||
#define BUFFER_WRITE_32(segment, accessAddress, startAddress, value) segment[accessAddress - startAddress] = value >> 24; segment[accessAddress - startAddress + 1] = (value >> 16) & 0xFF; segment[accessAddress - startAddress + 2] = (value >> 8) & 0xFF; segment[accessAddress - startAddress + 3] = value & 0xFF
|
||||
|
||||
//memory banks
|
||||
enum{
|
||||
EMPTY_BANK = 0,
|
||||
RAM_BANK,
|
||||
ROM_BANK,
|
||||
REG_BANK,
|
||||
SED1376_REG_BANK,
|
||||
SED1376_FB_BANK,
|
||||
UNSAFE_BANK//if a chip select uses base address bits 15 or 14 accesses wont be bank aligned and will use "if(address >= chips[chip].start && address <= chips[chip].start + chips[chip].size)"
|
||||
};
|
||||
|
||||
//types
|
||||
typedef struct{
|
||||
unsigned int (*read8)(unsigned int address);
|
||||
unsigned int (*read16)(unsigned int address);
|
||||
|
||||
Reference in New Issue
Block a user