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