From caef2dfe96d791fa383fc6c137eeaf4fc9e026b6 Mon Sep 17 00:00:00 2001 From: meepingsnesroms Date: Tue, 17 Apr 2018 12:03:50 -0700 Subject: [PATCH] Major chipselect overhaul Does not compile yet --- src/emulator.h | 33 +----- src/hardwareRegisters.c | 225 ++++++++++++++++++++++++++++++++++++---- src/hardwareRegisters.h | 25 +++++ src/memoryAccess.c | 61 +++++------ src/memoryAccess.h | 34 ++++++ 5 files changed, 292 insertions(+), 86 deletions(-) diff --git a/src/emulator.h b/src/emulator.h index 07344eb..63df1b4 100644 --- a/src/emulator.h +++ b/src/emulator.h @@ -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 diff --git a/src/hardwareRegisters.c b/src/hardwareRegisters.c index 02c4447..3be2b9b 100644 --- a/src/hardwareRegisters.c +++ b/src/hardwareRegisters.c @@ -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); diff --git a/src/hardwareRegisters.h b/src/hardwareRegisters.h index 92ee59e..b7878dc 100644 --- a/src/hardwareRegisters.h +++ b/src/hardwareRegisters.h @@ -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; diff --git a/src/memoryAccess.c b/src/memoryAccess.c index 69b6aa5..e6e68e2 100644 --- a/src/memoryAccess.c +++ b/src/memoryAccess.c @@ -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); } } diff --git a/src/memoryAccess.h b/src/memoryAccess.h index 785226f..efbd6bd 100644 --- a/src/memoryAccess.h +++ b/src/memoryAccess.h @@ -2,6 +2,28 @@ #include +//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);