Simplified load and write switch mem adress

This commit is contained in:
Blue 2019-05-23 10:28:12 +02:00
parent d70944a392
commit d569de3e38

View file

@ -14,17 +14,17 @@ namespace ProjectPSX {
private byte[] IO = new byte[512];
//Other Subsystems
public InterruptController interruptController;
private DMA dma;
private GPU gpu;
private GPUTest gpu;
private CDROM cdrom;
private InterruptController interruptController;
private TIMERS timers;
private JOYPAD joypad;
public BUS() {
interruptController = new InterruptController(); //refactor this to interface and callbacks
dma = new DMA();
gpu = new GPU();
gpu = new GPUTest();
cdrom = new CDROM();
timers = new TIMERS();
joypad = new JOYPAD();
@ -38,32 +38,21 @@ namespace ProjectPSX {
}
internal uint load(Width w, uint addr) {
addr &= RegionMask[addr >> 29];
switch (addr) {
case uint KUSEG when addr >= 0x0000_0000 && addr < 0x1F00_0000:
case uint KSEG0 when addr >= 0x8000_0000 && addr < 0x9F00_0000:
case uint KSEG1 when addr >= 0xA000_0000 && addr < 0xBF00_0000:
addr &= 0x1F_FFFF;
return load(w, addr, RAM);
case uint KUSEG when addr < 0x1F00_0000:
return load(w, addr & 0x1F_FFFF, RAM);
case uint KUSEG when addr >= 0x1F00_0000 && addr < 0x1F08_0000:
case uint KSEG0 when addr >= 0x9F00_0000 && addr < 0x9F08_0000:
case uint KSEG1 when addr >= 0xBF00_0000 && addr < 0xBF08_0000:
if (addr == 0x1F02_0018) {
Console.WriteLine("Load ON SWITCH EX");
}
addr &= 0x7_FFFF;
return load(w, addr, EX1);
return load(w, addr & 0x7_FFFF, EX1);
case uint KUSEG when addr >= 0x1F80_0000 && addr < 0x1F80_0400:
case uint KSEG0 when addr >= 0x9F80_0000 && addr < 0x9F80_0400:
case uint KSEG1 when addr >= 0xBF80_0000 && addr < 0xBF80_0400:
addr &= 0xFFF;
return load(w, addr, SCRATHPAD);
return load(w, addr & 0xFFF, SCRATHPAD);
case uint KUSEG when addr >= 0x1F80_1000 && addr < 0x1F80_2000:
case uint KSEG0 when addr >= 0x9F80_1000 && addr < 0x9F80_2000:
case uint KSEG1 when addr >= 0xBF80_1000 && addr < 0xBF80_2000:
switch (addr) {
case 0x1F801070:
return interruptController.loadISTAT();
@ -73,8 +62,9 @@ namespace ProjectPSX {
return joypad.load(w, addr);
case uint DMA when addr >= 0x1F80_1080 && addr <= 0x1F80_10FF:
return dma.load(w, addr);
//case uint TIMERS when addr >= 0x1F80_1100 && addr <= 0x1F80_112B:
//return timers.load(w, addr);
case uint TIMERS when addr >= 0x1F80_1100 && addr <= 0x1F80_112B:
//Console.WriteLine("[TIMERS] Load " + addr.ToString("x8"));
return timers.load(w, addr);
case uint CDROM when addr >= 0x1F80_1800 && addr <= 0x1F80_1803:
return cdrom.load(w, addr);
case 0x1F801810:
@ -82,59 +72,49 @@ namespace ProjectPSX {
case 0x1F801814:
return gpu.loadGPUSTAT();
default:
addr &= 0xFFF;
return load(w, addr, REGISTERS);
//return 0;
return load(w, addr & 0xFFF, REGISTERS);
}
case uint KUSEG when addr >= 0x1F80_2000 && addr < 0x1F80_2100:
return 0; //nocash bios tests
case uint KUSEG when addr >= 0x1FC0_0000 && addr < 0x1FC8_0000:
case uint KSEG0 when addr >= 0x9FC0_0000 && addr < 0x9FC8_0000:
case uint KSEG1 when addr >= 0xBFC0_0000 && addr < 0xBFC8_0000:
addr &= 0x7_FFFF;
return load(w, addr, BIOS);
return load(w, addr & 0x7_FFFF, BIOS);
case uint KSEG2 when addr >= 0xFFFE_0000 && addr < 0xFFFE_0200:
addr &= 0x1FF;
return load(w, addr, IO);
return load(w, addr & 0x1FF, IO);
default:
Console.WriteLine("[BUS] Load Unsupported: " + addr.ToString("x4"));
Console.ReadLine();
return 0xFFFF_FFFF;
}
}
private uint maskAddr(uint addr) {
uint i = addr >> 29;
return addr & RegionMask[i];
}
internal void write(Width w, uint addr, uint value) {
addr &= RegionMask[addr >> 29];
switch (addr) {
case uint KUSEG when addr >= 0x0000_0000 && addr < 0x1F00_0000:
case uint KSEG0 when addr >= 0x8000_0000 && addr < 0x9F00_0000:
case uint KSEG1 when addr >= 0xA000_0000 && addr < 0xBF00_0000:
addr &= 0x1F_FFFF;
write(w, addr, value, RAM);
case uint KUSEG when addr < 0x1F00_0000:
write(w, addr & 0x1F_FFFF, value, RAM);
break;
case uint KUSEG when addr >= 0x1F00_0000 && addr < 0x1F08_0000:
case uint KSEG0 when addr >= 0x9F00_0000 && addr < 0x9F08_0000:
case uint KSEG1 when addr >= 0xBF00_0000 && addr < 0xBF08_0000:
if(addr == 0x1F02_0018) {
if (addr == 0x1F02_0018) {
Console.WriteLine("Write ON SWITCH EX");
}
addr &= 0x7_FFFF;
Console.WriteLine("addr" + addr.ToString("x8"));
write(w, addr, value, EX1);
//Console.WriteLine("addr" + addr.ToString("x8")); //CAETLA DEBUG
write(w, addr & 0x7_FFFF, value, EX1);
break;
case uint KUSEG when addr >= 0x1F80_0000 && addr < 0x1F80_0400:
case uint KSEG0 when addr >= 0x9F80_0000 && addr < 0x9F80_0400:
case uint KSEG1 when addr >= 0xBF80_0000 && addr < 0xBF80_0400:
addr &= 0xFFF;
write(w, addr, value, SCRATHPAD);
write(w, addr & 0xFFF, value, SCRATHPAD);
break;
case uint KUSEG when addr >= 0x1F80_1000 && addr < 0x1F80_2000:
case uint KSEG0 when addr >= 0x9F80_1000 && addr < 0x9F80_2000:
case uint KSEG1 when addr >= 0xBF80_1000 && addr < 0xBF80_2000:
switch (addr) {
case 0x1F801070:
interruptController.writeISTAT(value);
@ -148,9 +128,10 @@ namespace ProjectPSX {
case uint DMA when addr >= 0x1F80_1080 && addr <= 0x1F80_10FF:
dma.write(w, addr, value);
break;
//case uint TIMERS when addr >= 0x1F80_1100 && addr <= 0x1F80_112B:
//timers.write(w, addr, value);
//break;
case uint TIMERS when addr >= 0x1F80_1100 && addr <= 0x1F80_112B:
//Console.WriteLine("[TIMERS] Write " +addr.ToString("x8") + value.ToString("x8"));
timers.write(w, addr, value);
break;
case uint CDROM when addr >= 0x1F80_1800 && addr <= 0x1F80_1803:
cdrom.write(w, addr, value);
break;
@ -169,15 +150,11 @@ namespace ProjectPSX {
break;
case uint KUSEG when addr >= 0x1FC0_0000 && addr < 0x1FC8_0000:
case uint KSEG0 when addr >= 0x9FC0_0000 && addr < 0x9FC8_0000:
case uint KSEG1 when addr >= 0xBFC0_0000 && addr < 0xBFC8_0000: //BIOS mem map
Console.WriteLine("[BUS] [WARNING] Write on BIOS range" + addr.ToString("x8"));
Console.ReadLine();
break;
case uint KSEG2 when addr >= 0xFFFE_0000 && addr < 0xFFFE_0200:
addr &= 0x1FF;
write(w, addr, value, IO);
write(w, addr & 0x1FF, value, IO);
break;
default:
@ -187,21 +164,26 @@ namespace ProjectPSX {
}
internal uint load(Width w, uint addr, byte[] memory) {
uint load = 0;
for (int i = 0; i < (byte)w; i++) {
load |= (uint)(memory[addr + i] << (8 * i));
switch (w) {
case Width.WORD: return (uint)(memory[addr + 3] << 24 | memory[addr + 2] << 16 | memory[addr + 1] << 8 | memory[addr]);
case Width.BYTE: return memory[addr];
case Width.HALF: return (uint)(memory[addr + 1] << 8 | memory[addr]);
default: return 0xFFFF_FFFF;
}
return load;
}
internal void write(Width w, uint addr, uint value, byte[] memory) {
for (int i = 0; i < (byte)w; i++) {
memory[addr + i] = (byte)(value >> (8 * i));
switch (w) {
case Width.WORD:
memory[addr] = (byte)value; memory[addr + 1] = (byte)(value >> 8);
memory[addr + 2] = (byte)(value >> 16); memory[addr + 3] = (byte)(value >> 24); break;
case Width.BYTE: memory[addr] = (byte)value; break;
case Width.HALF: memory[addr] = (byte)value; memory[addr + 1] = (byte)(value >> 8); break;
}
}
string psx = "./SCPH1001.BIN";
string noc = "./PSX-XBOO.ROM";
string no = "./nocashBios.ROM";
internal void loadBios() {
byte[] rom = File.ReadAllBytes(psx);
Array.Copy(rom, 0, BIOS, 0, rom.Length);
@ -209,7 +191,7 @@ namespace ProjectPSX {
//PSX executables are having an 800h-byte header, followed by the code/data.
//
// 000h-007h ASCII ID "PS-X EXE"
// 000h-007h ASCII ID "PS-x EXE"
// 008h-00Fh Zerofilled
// 010h Initial PC(usually 80010000h, or higher)
// 014h Initial GP/R28(usually 0)
@ -245,19 +227,19 @@ namespace ProjectPSX {
return (PC, R28, R29, R30);
}
string ex = "./EXPROM.BIN";
string nochas = "./PSX-EXP.ROM";
string caetla = "./caetlaEXP.BIN";
internal void loadEXP() {
byte[] exe = File.ReadAllBytes(ex);
byte[] exe = File.ReadAllBytes(caetla);
Array.Copy(exe, 0, EX1, 0, exe.Length);
}
public void tick(uint cycles) {
public void tick(int cycles) {
if (gpu.tick(cycles)) interruptController.set(Interrupt.VBLANK);
if (cdrom.tick(cycles)) interruptController.set(Interrupt.CDROM);
//if (timers.tick(0, cycles)) interruptController.set(Interrupt.TIMER0);
//if (timers.tick(1, cycles)) interruptController.set(Interrupt.TIMER1);
//if (timers.tick(2, cycles)) interruptController.set(Interrupt.TIMER2);
if (cdrom.tick(cycles/3)) interruptController.set(Interrupt.CDROM);
if (dma.tick()) interruptController.set(Interrupt.DMA);
if (timers.tick(0, cycles/3)) interruptController.set(Interrupt.TIMER0);
if (timers.tick(1, cycles/3)) interruptController.set(Interrupt.TIMER1);
if (timers.tick(2, cycles/3)) interruptController.set(Interrupt.TIMER2);
if (joypad.tick(cycles)) interruptController.set(Interrupt.CONTR);
}
@ -274,11 +256,18 @@ namespace ProjectPSX {
}
uint DMA_Transfer.fromGPU() {
return gpu.loadGPUSTAT();
return gpu.loadGPUREAD();
}
uint DMA_Transfer.fromCD() {
return cdrom.getData();
}
private readonly uint[] RegionMask = {
0xFFFF_FFFF, 0xFFFF_FFFF, 0xFFFF_FFFF, 0xFFFF_FFFF, // KUSEG: 2048MB
0x7FFF_FFFF, // KSEG0: 512MB
0x1FFF_FFFF, // KSEG1: 512MB
0xFFFF_FFFF, 0xFFFF_FFFF, // KSEG2: 1024MB
};
}
}