Start adding write protect

This commit is contained in:
meepingsnesroms
2018-04-17 13:42:53 -07:00
parent c26ec4013b
commit 992a1cd703
5 changed files with 117 additions and 57 deletions

View File

@@ -75,7 +75,6 @@ static void invalidBehaviorCheck(){
//add to opcode buffer
strcpy(disassemblyBuffer[LOGGED_OPCODES - 1], opcodeName);
strcat(disassemblyBuffer[LOGGED_OPCODES - 1], "\n");
if(invalidInstruction || invalidBank || (instruction == 0x0000 && lastProgramCounter != 0x00000000)){
//0x0000 is "ori.b #$0, D0", effectivly NOP but still a valid opcode
@@ -84,7 +83,7 @@ static void invalidBehaviorCheck(){
invalidBehaviorAbort = true;
for(uint32_t i = 0; i < LOGGED_OPCODES; i++)
debugLog(disassemblyBuffer[i]);
debugLog("%s\n", disassemblyBuffer[i]);
//currently CPU32 opcodes will be listed as "unknown", I cant change that properly unless I directly edit musashi source, something I want to avoid doing
debugLog("Instruction:\"%s\", instruction value:0x%04X, program counter:0x%08X\n", invalidInstruction ? "unknown" : opcodeName, instruction, programCounter);
}
@@ -116,7 +115,7 @@ void emulatorInit(uint8_t* palmRomDump, uint8_t* palmBootDump, uint32_t specialF
memcpy(palmReg + REG_SIZE - 1 - BOOTLOADER_SIZE, palmBootDump, BOOTLOADER_SIZE);
else
memset(palmReg + REG_SIZE - 1 - BOOTLOADER_SIZE, 0x00, BOOTLOADER_SIZE);
memcpy(palmRam, palmRom, 256);//copy ROM header
//memcpy(palmRam, palmRom, 256);//copy ROM header
//memcpy(palmRam, palmRom, ROM_SIZE);//copy whole ROM
memcpy(&palmFramebuffer[160 * 160], silkscreenData, SILKSCREEN_WIDTH * SILKSCREEN_HEIGHT * (SILKSCREEN_BPP / 8));
resetAddressSpace();

View File

@@ -10,9 +10,10 @@
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, should trigger access exceptions if enabled
static unsigned int unmappedRead(unsigned int address){return 0x00000000;}
static void unmappedWrite(unsigned int address, unsigned int value){}
//used for unmapped address space and writes to write protected chipselects, should trigger access exceptions if enabled
static unsigned int invalidRead(unsigned int address){return 0x00000000;}
static void invalidWrite(unsigned int address, unsigned int value){}
//RAM accesses
static unsigned int ramRead8(unsigned int address){return BUFFER_READ_8(palmRam, address, chips[CHIP_D_RAM].start, chips[CHIP_D_RAM].mask);}
@@ -26,6 +27,8 @@ static void ramWrite32(unsigned int address, unsigned int value){BUFFER_WRITE_32
static unsigned int romRead8(unsigned int address){return BUFFER_READ_8(palmRom, address, chips[CHIP_A_ROM].start, chips[CHIP_A_ROM].mask);}
static unsigned int romRead16(unsigned int address){return BUFFER_READ_16(palmRom, address, chips[CHIP_A_ROM].start, chips[CHIP_A_ROM].mask);}
static unsigned int romRead32(unsigned int address){return BUFFER_READ_32(palmRom, address, chips[CHIP_A_ROM].start, chips[CHIP_A_ROM].mask);}
//the validity of attempting to write to ROM is determined by the read only bit in CSA, either way the write will do nothing
static void romWrite(unsigned int address, unsigned int value){}
//SED1376 framebuffer
static unsigned int sed1376FramebufferRead8(unsigned int address){return BUFFER_READ_8(sed1376Framebuffer, address, chips[CHIP_B_SED].start + SED1376_REG_SIZE, chips[CHIP_B_SED].mask);}
@@ -83,102 +86,159 @@ static uint8_t getProperBankType(uint16_t bank){
return EMPTY_BANK;
}
static void setBankType(uint16_t bank, uint8_t type){
static bool getBankProtection(uint16_t bank){
//special conditions
if((bank & 0x00FF) == 0x00FF && registersAreXXFFMapped()){
//XXFF register mode
return false;
}
//normal banks
else if(chips[CHIP_A_ROM].enable && BANK_IN_RANGE(bank, chips[CHIP_A_ROM].start, chips[CHIP_A_ROM].size)){
return chips[CHIP_A_ROM].readOnly;//CSA has no protected memory segment
}
if(chips[CHIP_D_RAM].enable && BANK_IN_RANGE(bank, chips[CHIP_D_RAM].start, chips[CHIP_D_RAM].size)){
return BANK_READ_ONLY(bank, CHIP_D_RAM);
}
else if(chips[CHIP_B_SED].enable && BANK_IN_RANGE(bank, chips[CHIP_B_SED].start, chips[CHIP_B_SED].size) && sed1376ClockConnected()){
return BANK_READ_ONLY(bank, CHIP_B_SED);
}
else if(BANK_IN_RANGE(bank, REG_START_ADDRESS, REG_SIZE)){
return false;
}
return false;
}
static void setBankType(uint16_t bank, uint8_t type, bool writeProtected){
bankType[bank] = type;
//read handlers
switch(type){
case EMPTY_BANK:
bankAccessors[bank].read8 = unmappedRead;
bankAccessors[bank].read16 = unmappedRead;
bankAccessors[bank].read32 = unmappedRead;
bankAccessors[bank].write8 = unmappedWrite;
bankAccessors[bank].write16 = unmappedWrite;
bankAccessors[bank].write32 = unmappedWrite;
bankAccessors[bank].read8 = invalidRead;
bankAccessors[bank].read16 = invalidRead;
bankAccessors[bank].read32 = invalidRead;
break;
case RAM_BANK:
bankAccessors[bank].read8 = ramRead8;
bankAccessors[bank].read16 = ramRead16;
bankAccessors[bank].read32 = ramRead32;
bankAccessors[bank].write8 = ramWrite8;
bankAccessors[bank].write16 = ramWrite16;
bankAccessors[bank].write32 = ramWrite32;
break;
case ROM_BANK:
bankAccessors[bank].read8 = romRead8;
bankAccessors[bank].read16 = romRead16;
bankAccessors[bank].read32 = romRead32;
bankAccessors[bank].write8 = unmappedWrite;
bankAccessors[bank].write16 = unmappedWrite;
bankAccessors[bank].write32 = unmappedWrite;
break;
case REG_BANK:
bankAccessors[bank].read8 = getHwRegister8;
bankAccessors[bank].read16 = getHwRegister16;
bankAccessors[bank].read32 = getHwRegister32;
bankAccessors[bank].write8 = setHwRegister8;
bankAccessors[bank].write16 = setHwRegister16;
bankAccessors[bank].write32 = setHwRegister32;
break;
case SED1376_REG_BANK:
bankAccessors[bank].read8 = sed1376GetRegister;
bankAccessors[bank].read16 = sed1376GetRegister;
bankAccessors[bank].read32 = sed1376GetRegister;
bankAccessors[bank].write8 = sed1376SetRegister;
bankAccessors[bank].write16 = sed1376SetRegister;
bankAccessors[bank].write32 = sed1376SetRegister;
break;
case SED1376_FB_BANK:
bankAccessors[bank].read8 = sed1376FramebufferRead8;
bankAccessors[bank].read16 = sed1376FramebufferRead16;
bankAccessors[bank].read32 = sed1376FramebufferRead32;
bankAccessors[bank].write8 = sed1376FramebufferWrite8;
bankAccessors[bank].write16 = sed1376FramebufferWrite16;
bankAccessors[bank].write32 = sed1376FramebufferWrite32;
break;
}
//write handlers
if(!writeProtected){
switch(type){
case EMPTY_BANK:
bankAccessors[bank].write8 = invalidWrite;
bankAccessors[bank].write16 = invalidWrite;
bankAccessors[bank].write32 = invalidWrite;
break;
case RAM_BANK:
bankAccessors[bank].write8 = ramWrite8;
bankAccessors[bank].write16 = ramWrite16;
bankAccessors[bank].write32 = ramWrite32;
break;
case ROM_BANK:
bankAccessors[bank].write8 = romWrite;
bankAccessors[bank].write16 = romWrite;
bankAccessors[bank].write32 = romWrite;
break;
case REG_BANK:
bankAccessors[bank].write8 = setHwRegister8;
bankAccessors[bank].write16 = setHwRegister16;
bankAccessors[bank].write32 = setHwRegister32;
break;
case SED1376_REG_BANK:
bankAccessors[bank].write8 = sed1376SetRegister;
bankAccessors[bank].write16 = sed1376SetRegister;
bankAccessors[bank].write32 = sed1376SetRegister;
break;
case SED1376_FB_BANK:
bankAccessors[bank].write8 = sed1376FramebufferWrite8;
bankAccessors[bank].write16 = sed1376FramebufferWrite16;
bankAccessors[bank].write32 = sed1376FramebufferWrite32;
break;
}
}
else{
bankAccessors[bank].write8 = invalidWrite;
bankAccessors[bank].write16 = invalidWrite;
bankAccessors[bank].write32 = invalidWrite;
}
}
void setRegisterXXFFAccessMode(){
for(uint16_t topByte = 0; topByte < 0x100; topByte++){
uint32_t bank = topByte << 8 | 0xFF;
setBankType(bank, REG_BANK);
setBankType(bank, REG_BANK, false);
}
}
void setRegisterFFFFAccessMode(){
for(uint16_t topByte = 0; topByte < 0x100; topByte++){
uint32_t bank = topByte << 8 | 0xFF;
setBankType(bank, getProperBankType(bank));
setBankType(bank, getProperBankType(bank), getBankProtection(bank));
}
}
void setSed1376Attached(bool attached){
if(attached){
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);
if(chips[CHIP_B_SED].enable){
if(attached){
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, getBankProtection(bank));
else
setBankType(bank, SED1376_FB_BANK, getBankProtection(bank));
}
}
}
else{
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);
else{
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, getBankProtection(bank));
}
}
}
}
void refreshBankHandlers(){
for(uint32_t bank = 0; bank < TOTAL_MEMORY_BANKS; bank++)
setBankType(bank, bankType[bank]);
setBankType(bank, bankType[bank], getBankProtection(bank));
}
void resetAddressSpace(){
for(uint32_t bank = 0; bank < TOTAL_MEMORY_BANKS; bank++)
setBankType(bank, getProperBankType(bank));
setBankType(bank, getProperBankType(bank), getBankProtection(bank));
}

View File

@@ -7,11 +7,11 @@
#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 BANK_ADDRESS(bank) (bank << 16)
#define BANK_READ_ONLY(bank, chip) (chips[chip].readOnly || (chips[chip].readOnlyForProtectedMemory && (BANK_ADDRESS(bank) - chips[chip].start) >= chips[chip].unprotectedSize))
#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
@@ -19,8 +19,6 @@
#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

View File

@@ -2,24 +2,25 @@
#include <string.h>
#include "emulator.h"
#include "hardwareRegisters.h"
//the SED1376 has only 16 address lines(17 if you count the line that switches between registers and framebuffer) and 16 data lines, the most you can read is 16 bits, registers are 8 bits
//the actions described below are just my best guesses after reading the datasheet, I have not tested with actual hardware
//you read and write the register on the address lines set
//8 bit reg access works normal
//16 bit reg reads will result in you getting (0x00 << 8 | register).
//16 bit reg writes will result in you writing the lower 8 bits.
//8 bit register access works normal
//16 bit register reads will result in you getting (0x00 << 8 | register).
//16 bit register writes will result in you writing the lower 8 bits.
//32 bit register reads will result in you getting (randomUint16 << 16 | 0x00 << 8 | register), upper 16 bits are floating because SED1376 only has 16 address lines.
//32 bit register writes will result in you writing the lower 8 bits.
//The LCD power-on sequence is activated by programming the Power Save Mode Enable bit (REG[A0h] bit 0) to 0.
//The LCD power-off sequence is activated by programming the Power Save Mode Enable bit (REG[A0h] bit 0) to 1.
uint8_t sed1376Registers[SED1376_REG_SIZE];
uint8_t sed1376Framebuffer[SED1376_FB_SIZE + 3];//+ 3 to prevent 32 bit writes on last byte from corrupting memory
uint8_t sed1376Framebuffer[SED1376_FB_SIZE];
unsigned int sed1376GetRegister(unsigned int address){
@@ -43,9 +44,9 @@ void sed1376Reset(){
}
void sed1376Render(){
if(palmMisc.lcdOn && palmMisc.backlightOn){
//only render if lcd on and backlight on
if(palmMisc.lcdOn && palmMisc.backlightOn && cpuIsOn()){
//only render if LCD on and backlight on, SED1376 clock is provided by the CPU, if its off so is the SED
}
else{
//black screen

View File

@@ -5,19 +5,19 @@ sysTrapPceNativeCall, ARM Emulator
cpu32 table lookup opcodes
Peripheral Control Register, audio ppm mixing selection
All edge triggered interrupts(currently always level triggered)
The boot memory mapping where ROM starts at 0x00000000 and RAM is swapped in
(debug tools)missing icons
Port G SPI stuff
RAM location and size setting, Dragonball VZ can set the page mapping SDCTRL
DRAMC write enable
All of DRAMMC
All chip select registers
Setting the battery dead bit(PDDATA 0x80) if the emulated battery percent gets too low
Sdcard can't be read or written to
Sdcard can't be inserted or removed
Sdcard has no error handling in save/load state
Port M Infrared shutdown (PMDATA 0x20)
interrupt control register (ICR) partially unimplemented
interrupt control register (ICR), POL5 and edge trigger selects
Bits 15 and 14 of the chip selects, currently only the upper 16 bits are taken into account
Supervisor only chip select bits
Fixed:
System Control Register, 0xXXFFF000 all upper banks are registers mode
@@ -28,3 +28,5 @@ PLL Control Register, Wake Select
(Resolved by MC68VZ328UM_CORRECTIONS datasheet, its 0xA28, 16 bits)The data sheet says LRRA is 0xFFFFFA29 and 0xFFFFFA28 but its only 8 bits?
(All except edge triggered INT0/1/2/3 restart PLL)Check if interrupts restart PLL when its disabled
Disabling PLL also turns off general purpose timer 1 and 2 unless they are set to use clk32 as there source
All chip select registers
The boot memory mapping where ROM starts at 0x00000000 and RAM is swapped in