mirror of
https://github.com/BluestormDNA/ProjectPSX.git
synced 2025-04-02 10:52:34 -04:00
Refactor
This commit is contained in:
parent
c11d21c7f2
commit
da19b7ee91
8 changed files with 206 additions and 110 deletions
|
@ -1,9 +1,11 @@
|
|||
using System;
|
||||
using ProjectPSX.Devices;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace ProjectPSX {
|
||||
internal class MMU {
|
||||
internal class BUS {
|
||||
|
||||
//Memory
|
||||
private byte[] RAM = new byte[2048 * 1024];
|
||||
private byte[] EX1 = new byte[512 * 1024];
|
||||
private byte[] SCRATHPAD = new byte[1024];
|
||||
|
@ -11,11 +13,17 @@ namespace ProjectPSX {
|
|||
private byte[] BIOS = new byte[512 * 1024];
|
||||
private byte[] IO = new byte[512];
|
||||
|
||||
//Other Subsystems
|
||||
private DMA dma;
|
||||
|
||||
public BUS() {
|
||||
dma = new DMA();
|
||||
}
|
||||
|
||||
private const uint GPUSTAT = 0x1f801814;
|
||||
private const uint GP0 = 0x1f801810;
|
||||
|
||||
internal uint read32(uint addr) {
|
||||
//Console.WriteLine("READ ADDR: " + addr.ToString("x4"));
|
||||
internal uint load32(uint addr) {
|
||||
switch (addr) {
|
||||
case uint KUSEG when addr >= 0x0000_0000 && addr < 0x1F00_0000:
|
||||
case uint KSEG0 when addr >= 0x8000_0000 && addr < 0x9F00_0000:
|
||||
|
@ -39,29 +47,22 @@ namespace ProjectPSX {
|
|||
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:
|
||||
if (addr >= 0x1f801080 && addr <= 0x1f8010FF) {
|
||||
Console.WriteLine("DMA ACCESS");
|
||||
return 0;
|
||||
} else if (addr == GPUSTAT) { Console.WriteLine("GPUSTAT ACCESS"); return 0x1000_0000; }
|
||||
else if (addr == GP0) { Console.WriteLine("GP0 ACCESS"); return 0; }
|
||||
else if (addr == 0x1f801104) { Console.WriteLine("Timer 1104 ACCESS"); return 0; }
|
||||
else if (addr == 0x1f801114) { Console.WriteLine("Timer 1114 ACCESS"); return 0; }
|
||||
else if (addr == 0x1f801118) { Console.WriteLine("Timer 1118 ACCESS"); return 0; }
|
||||
else if (addr == 0x1f801070) { Console.WriteLine("Interrupt Mask ACCESS"); return 0; }
|
||||
else if (addr == 0x1f801074) { Console.WriteLine("Interrupt Status ACCESS"); return 0; }
|
||||
else if (addr == 0x1f801dae) { Console.WriteLine("SPU ACCESS"); return 0; }
|
||||
if (addr == GPUSTAT) { Console.WriteLine("GPUSTAT ACCESS"); return 0x1000_0000; } else if (addr == GP0) { Console.WriteLine("GP0 ACCESS"); return 0; } else if (addr == 0x1f801104) { Console.WriteLine("Timer 1104 ACCESS"); return 0; } else if (addr == 0x1f801114) { Console.WriteLine("Timer 1114 ACCESS"); return 0; } else if (addr == 0x1f801118) { Console.WriteLine("Timer 1118 ACCESS"); return 0; } else if (addr == 0x1f801070) { Console.WriteLine("Interrupt Mask ACCESS"); return 0; } else if (addr == 0x1f801074) { Console.WriteLine("Interrupt Status ACCESS"); return 0; } else if (addr == 0x1f801dae) { Console.WriteLine("SPU ACCESS"); return 0; }
|
||||
|
||||
switch (addr) {
|
||||
case uint DMA when addr >= 0x1F80_1080 && addr < 0x1F80_10FF:
|
||||
Console.WriteLine("load at addr {0} = {1}", addr.ToString("x8"), dma.load32(addr).ToString("x8"));
|
||||
return dma.load32(addr);
|
||||
|
||||
default:
|
||||
addr &= 0xFFF;
|
||||
return (uint)((REGISTERS[addr + 3] << 24) | (REGISTERS[addr + 2] << 16) | (REGISTERS[addr + 1] << 8) | REGISTERS[addr]);
|
||||
}
|
||||
|
||||
addr &= 0xFFF;
|
||||
return (uint)((REGISTERS[addr + 3] << 24) | (REGISTERS[addr + 2] << 16) | (REGISTERS[addr + 1] << 8) | REGISTERS[addr]);
|
||||
|
||||
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
|
||||
if (0xbfc04190 == addr) {
|
||||
Console.WriteLine("DMA LOOP");
|
||||
return 0;
|
||||
}
|
||||
|
||||
addr &= 0x7_FFFF;
|
||||
return (uint)((BIOS[addr + 3] << 24) | (BIOS[addr + 2] << 16) | (BIOS[addr + 1] << 8) | BIOS[addr]);
|
||||
|
||||
|
@ -86,6 +87,7 @@ namespace ProjectPSX {
|
|||
RAM[addr + 2] = (byte)(value >> 16);
|
||||
RAM[addr + 3] = (byte)(value >> 24);
|
||||
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:
|
||||
|
@ -95,6 +97,7 @@ namespace ProjectPSX {
|
|||
EX1[addr + 2] = (byte)(value >> 16);
|
||||
EX1[addr + 3] = (byte)(value >> 24);
|
||||
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:
|
||||
|
@ -104,21 +107,33 @@ namespace ProjectPSX {
|
|||
SCRATHPAD[addr + 2] = (byte)(value >> 16);
|
||||
SCRATHPAD[addr + 3] = (byte)(value >> 24);
|
||||
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:
|
||||
addr &= 0xFFF;
|
||||
REGISTERS[addr] = (byte)(value);
|
||||
REGISTERS[addr + 1] = (byte)(value >> 8);
|
||||
REGISTERS[addr + 2] = (byte)(value >> 16);
|
||||
REGISTERS[addr + 3] = (byte)(value >> 24);
|
||||
|
||||
switch (addr) {
|
||||
case uint DMA when addr >= 0x1F80_1080 && addr < 0x1F80_10FF:
|
||||
dma.write32(addr, value);
|
||||
break;
|
||||
|
||||
default:
|
||||
addr &= 0xFFF;
|
||||
REGISTERS[addr] = (byte)(value);
|
||||
REGISTERS[addr + 1] = (byte)(value >> 8);
|
||||
REGISTERS[addr + 2] = (byte)(value >> 16);
|
||||
REGISTERS[addr + 3] = (byte)(value >> 24);
|
||||
break;
|
||||
}
|
||||
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("WARNING WRITE 32 on BIOS RANGE" + addr.ToString("x8"));
|
||||
Console.ReadLine();
|
||||
break;
|
||||
|
||||
case uint KSEG2 when addr >= 0xFFFE_0000 && addr < 0xFFFE_0200:
|
||||
addr &= 0x1FF;
|
||||
IO[addr] = (byte)(value);
|
||||
|
@ -126,6 +141,7 @@ namespace ProjectPSX {
|
|||
IO[addr + 2] = (byte)(value >> 16);
|
||||
IO[addr + 3] = (byte)(value >> 24);
|
||||
break;
|
||||
|
||||
default:
|
||||
Console.WriteLine("Unsupported WRITE AREA: " + addr.ToString("x4") + ": " + value.ToString("x4"));
|
||||
break;
|
|
@ -80,19 +80,20 @@ namespace ProjectPSX {
|
|||
private WB wb;
|
||||
private MEM mem;
|
||||
|
||||
internal void Run(MMU mmu) {
|
||||
fetchDecode(mmu);
|
||||
Execute(mmu);
|
||||
internal void Run(BUS bus) {
|
||||
fetchDecode(bus);
|
||||
Execute(bus);
|
||||
MemAccess();
|
||||
WriteBack();
|
||||
TTY();
|
||||
|
||||
//debug
|
||||
TTY();
|
||||
//disassemble();
|
||||
//PrintRegs();
|
||||
}
|
||||
|
||||
private void fetchDecode(MMU mmu) {
|
||||
uint load = mmu.read32(PC);
|
||||
private void fetchDecode(BUS bus) {
|
||||
uint load = bus.load32(PC);
|
||||
PC_Now = PC;
|
||||
PC = PC_Predictor;
|
||||
PC_Predictor += 4;
|
||||
|
@ -122,7 +123,7 @@ namespace ProjectPSX {
|
|||
REG[0] = 0;
|
||||
}
|
||||
|
||||
private void Execute(MMU mmu) {
|
||||
private void Execute(BUS bus) {
|
||||
switch (instr.opcode) {
|
||||
case 0b00_0000: //R-Type opcodes
|
||||
switch (instr.function) {
|
||||
|
@ -196,26 +197,26 @@ namespace ProjectPSX {
|
|||
case 0b01_0010: COP2(); break;
|
||||
case 0b01_0011: COP3(); break;
|
||||
|
||||
case 0b10_0000: LB(mmu); break;
|
||||
case 0b10_0001: LH(mmu); break;
|
||||
case 0b10_0010: LWL(mmu); break;
|
||||
case 0b10_0011: LW(mmu); break;
|
||||
case 0b10_0100: LBU(mmu); break;
|
||||
case 0b10_0101: LHU(mmu); break;
|
||||
case 0b10_0110: LWR(mmu); break;
|
||||
case 0b10_1000: SB(mmu); break;
|
||||
case 0b10_1001: SH(mmu); break;
|
||||
case 0b10_1010: SWL(mmu); break;
|
||||
case 0b10_1011: SW(mmu); break;
|
||||
case 0b10_1110: SWR(mmu); break;
|
||||
case 0b10_0000: LB(bus); break;
|
||||
case 0b10_0001: LH(bus); break;
|
||||
case 0b10_0010: LWL(bus); break;
|
||||
case 0b10_0011: LW(bus); break;
|
||||
case 0b10_0100: LBU(bus); break;
|
||||
case 0b10_0101: LHU(bus); break;
|
||||
case 0b10_0110: LWR(bus); break;
|
||||
case 0b10_1000: SB(bus); break;
|
||||
case 0b10_1001: SH(bus); break;
|
||||
case 0b10_1010: SWL(bus); break;
|
||||
case 0b10_1011: SW(bus); break;
|
||||
case 0b10_1110: SWR(bus); break;
|
||||
case 0b11_0000: //LWC0
|
||||
case 0b11_0001: //LWC1
|
||||
case 0b11_0011: //LWC3
|
||||
case 0b11_1000: //SWC0
|
||||
case 0b11_1001: //SWC1
|
||||
case 0b11_1011: UNIMPL_LW_SW_COP0_1_3(); break;
|
||||
case 0b11_0010: LWC2(mmu); break;
|
||||
case 0b11_1010: SWC2(mmu); break;
|
||||
case 0b11_0010: LWC2(bus); break;
|
||||
case 0b11_1010: SWC2(bus); break;
|
||||
//pending lwc0-3 and swc0-3 and illegal opc
|
||||
default:
|
||||
EXCEPTION(EX.ILLEGAL_INSTR);
|
||||
|
@ -224,12 +225,12 @@ namespace ProjectPSX {
|
|||
}
|
||||
}
|
||||
|
||||
private void SWC2(MMU mmu) {
|
||||
private void SWC2(BUS bus) {
|
||||
Console.WriteLine("Store at GTE");
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void LWC2(MMU mmu) {
|
||||
private void LWC2(BUS bus) {
|
||||
Console.WriteLine("Load from GTE");
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
@ -238,11 +239,11 @@ namespace ProjectPSX {
|
|||
EXCEPTION(EX.COPROCESSOR_ERROR);
|
||||
}
|
||||
|
||||
private void SWR(MMU mmu) {
|
||||
private void SWR(BUS bus) {
|
||||
uint addr = REG[instr.rs] + instr.imm_s;
|
||||
uint aligned_addr = (uint)(addr & ~0b11);
|
||||
|
||||
uint aligned_load = mmu.read32(aligned_addr);
|
||||
uint aligned_load = bus.load32(aligned_addr);
|
||||
|
||||
uint value = 0;
|
||||
switch (addr & 0b11) {
|
||||
|
@ -252,14 +253,14 @@ namespace ProjectPSX {
|
|||
case 3: value = aligned_load & 0xFF_FFFF | REG[instr.rt] << 24; break;
|
||||
}
|
||||
|
||||
mmu.write32(addr, value);
|
||||
bus.write32(addr, value);
|
||||
}
|
||||
|
||||
private void SWL(MMU mmu) {
|
||||
private void SWL(BUS bus) {
|
||||
uint addr = REG[instr.rs] + instr.imm_s;
|
||||
uint aligned_addr = (uint)(addr & ~0b11);
|
||||
|
||||
uint aligned_load = mmu.read32(aligned_addr);
|
||||
uint aligned_load = bus.load32(aligned_addr);
|
||||
|
||||
uint value = 0;
|
||||
switch (addr & 0b11) {
|
||||
|
@ -269,14 +270,14 @@ namespace ProjectPSX {
|
|||
case 0: value = aligned_load & 0xFF_FFFF | REG[instr.rt] >> 24; break;
|
||||
}
|
||||
|
||||
mmu.write32(addr, value);
|
||||
bus.write32(addr, value);
|
||||
}
|
||||
|
||||
private void LWR(MMU mmu) {
|
||||
private void LWR(BUS bus) {
|
||||
uint addr = REG[instr.rs] + instr.imm_s;
|
||||
uint aligned_addr = (uint)(addr & ~0b11);
|
||||
|
||||
uint aligned_load = mmu.read32(aligned_addr);
|
||||
uint aligned_load = bus.load32(aligned_addr);
|
||||
|
||||
uint value = 0;
|
||||
switch (addr & 0b11) {
|
||||
|
@ -291,11 +292,11 @@ namespace ProjectPSX {
|
|||
delayedLoad(instr.rt, prev_value | value);
|
||||
}
|
||||
|
||||
private void LWL(MMU mmu) {
|
||||
private void LWL(BUS bus) {
|
||||
uint addr = REG[instr.rs] + instr.imm_s;
|
||||
uint aligned_addr = (uint)(addr & ~0b11);
|
||||
|
||||
uint aligned_load = mmu.read32(aligned_addr);
|
||||
uint aligned_load = bus.load32(aligned_addr);
|
||||
|
||||
uint value = 0;
|
||||
switch(addr & 0b11) {
|
||||
|
@ -372,14 +373,14 @@ namespace ProjectPSX {
|
|||
setReg(instr.rd, ~(REG[instr.rs] | REG[instr.rt]));
|
||||
}
|
||||
|
||||
private void LH(MMU mmu) {
|
||||
private void LH(BUS bus) {
|
||||
if ((SR & 0x10000) == 0) {
|
||||
uint addr = REG[instr.rs] + instr.imm_s;
|
||||
|
||||
if ((addr % 2) != 0) {
|
||||
EXCEPTION(EX.LOAD_ADRESS_ERROR);
|
||||
} else {
|
||||
uint value = (uint)(short)mmu.read32(addr);
|
||||
uint value = (uint)(short)bus.load32(addr);
|
||||
delayedLoad(instr.rt, value);
|
||||
}
|
||||
|
||||
|
@ -390,14 +391,14 @@ namespace ProjectPSX {
|
|||
setReg(instr.rd, REG[instr.rt] << (int)(REG[instr.rs] & 0x1F));
|
||||
}
|
||||
|
||||
private void LHU(MMU mmu) {
|
||||
private void LHU(BUS bus) {
|
||||
if ((SR & 0x10000) == 0) {
|
||||
uint addr = REG[instr.rs] + instr.imm_s;
|
||||
|
||||
if ((addr % 2) != 0) {
|
||||
EXCEPTION(EX.LOAD_ADRESS_ERROR);
|
||||
} else {
|
||||
uint value = (ushort)mmu.read32(addr);
|
||||
uint value = (ushort)bus.load32(addr);
|
||||
delayedLoad(instr.rt, value);
|
||||
}
|
||||
|
||||
|
@ -418,7 +419,7 @@ namespace ProjectPSX {
|
|||
LO = REG[instr.rs];
|
||||
}
|
||||
|
||||
private void EXCEPTION(uint cause) {
|
||||
private void EXCEPTION(EX cause) {
|
||||
uint ExAdress;
|
||||
if((SR & (1 << 22)) != 0) {
|
||||
ExAdress = 0xBFC0_0180;
|
||||
|
@ -430,7 +431,7 @@ namespace ProjectPSX {
|
|||
SR = (uint)(SR & ~0x3F);
|
||||
SR |= (mode << 2) & 0x3F;
|
||||
|
||||
CAUSE = cause << 2;
|
||||
CAUSE = (uint)cause << 2;
|
||||
EPC = PC_Now;
|
||||
|
||||
if (isDelaySlot) {
|
||||
|
@ -538,9 +539,9 @@ namespace ProjectPSX {
|
|||
JR();
|
||||
}
|
||||
|
||||
private void LBU(MMU mmu) { //todo recheck this
|
||||
private void LBU(BUS bus) { //todo recheck this
|
||||
if ((SR & 0x10000) == 0) {
|
||||
uint value = (byte)mmu.read32(REG[instr.rs] + instr.imm_s);
|
||||
uint value = (byte)bus.load32(REG[instr.rs] + instr.imm_s);
|
||||
delayedLoad(instr.rt, value);
|
||||
} //else Console.WriteLine("Ignoring Load");
|
||||
}
|
||||
|
@ -582,9 +583,9 @@ namespace ProjectPSX {
|
|||
}
|
||||
}
|
||||
|
||||
private void LB(MMU mmu) { //todo redo this as it unnecesary read32
|
||||
private void LB(BUS bus) { //todo redo this as it unnecesary load32
|
||||
if ((SR & 0x10000) == 0) {
|
||||
uint value = (uint)((sbyte)(mmu.read32(REG[instr.rs] + instr.imm_s)));
|
||||
uint value = (uint)((sbyte)(bus.load32(REG[instr.rs] + instr.imm_s)));
|
||||
delayedLoad(instr.rt, value);
|
||||
} //else Console.WriteLine("Ignoring Write");
|
||||
}
|
||||
|
@ -594,9 +595,9 @@ namespace ProjectPSX {
|
|||
PC_Predictor = REG[instr.rs];
|
||||
}
|
||||
|
||||
private void SB(MMU mmu) {
|
||||
private void SB(BUS bus) {
|
||||
if ((SR & 0x10000) == 0)
|
||||
mmu.write8(REG[instr.rs] + instr.imm_s, (byte)REG[instr.rt]);
|
||||
bus.write8(REG[instr.rs] + instr.imm_s, (byte)REG[instr.rt]);
|
||||
//else Console.WriteLine("Ignoring Write");
|
||||
}
|
||||
|
||||
|
@ -609,14 +610,14 @@ namespace ProjectPSX {
|
|||
J();
|
||||
}
|
||||
|
||||
private void SH(MMU mmu) {
|
||||
private void SH(BUS bus) {
|
||||
if ((SR & 0x10000) == 0) {
|
||||
uint addr = REG[instr.rs] + instr.imm_s;
|
||||
|
||||
if ((addr % 2) != 0) {
|
||||
EXCEPTION(EX.STORE_ADRESS_ERROR);
|
||||
} else {
|
||||
mmu.write16(addr, (ushort)REG[instr.rt]);
|
||||
bus.write16(addr, (ushort)REG[instr.rt]);
|
||||
}
|
||||
}
|
||||
//else Console.WriteLine("Ignoring Write");
|
||||
|
@ -631,14 +632,14 @@ namespace ProjectPSX {
|
|||
setReg(instr.rd, condition ? 1u : 0u);
|
||||
}
|
||||
|
||||
private void LW(MMU mmu) {
|
||||
private void LW(BUS bus) {
|
||||
if ((SR & 0x10000) == 0) {
|
||||
uint addr = REG[instr.rs] + instr.imm_s;
|
||||
|
||||
if ((addr % 4) != 0) {
|
||||
EXCEPTION(EX.LOAD_ADRESS_ERROR);
|
||||
} else {
|
||||
uint value = mmu.read32(addr);
|
||||
uint value = bus.load32(addr);
|
||||
delayedLoad(instr.rt, value);
|
||||
}
|
||||
|
||||
|
@ -683,14 +684,14 @@ namespace ProjectPSX {
|
|||
setReg(instr.rd, REG[instr.rt] << (int)instr.sa);
|
||||
}
|
||||
|
||||
private void SW(MMU mmu) {
|
||||
private void SW(BUS bus) {
|
||||
if ((SR & 0x10000) == 0) {
|
||||
uint addr = REG[instr.rs] + instr.imm_s;
|
||||
|
||||
if ((addr % 4) != 0) {
|
||||
EXCEPTION(EX.STORE_ADRESS_ERROR);
|
||||
} else {
|
||||
mmu.write32(addr, REG[instr.rt]);
|
||||
bus.write32(addr, REG[instr.rt]);
|
||||
}
|
||||
}
|
||||
//else Console.WriteLine("Ignoring Write");
|
||||
|
@ -857,36 +858,36 @@ namespace ProjectPSX {
|
|||
}
|
||||
break;
|
||||
|
||||
case 0b10_0000:// LB(mmu);
|
||||
case 0b10_0000:// LB(bus);
|
||||
output = "LB";
|
||||
break;
|
||||
case 0b10_0001: //LH(mmu); break;
|
||||
case 0b10_0001: //LH(bus); break;
|
||||
output = "LH";
|
||||
break;
|
||||
case 0b10_0010: output = "LWL"; break;
|
||||
case 0b10_0100:// LBU(mmu);
|
||||
case 0b10_0100:// LBU(bus);
|
||||
output = "LBU";
|
||||
break;
|
||||
case 0b10_0101: //LHU(mmu); break;
|
||||
case 0b10_0101: //LHU(bus); break;
|
||||
output = "LHU";
|
||||
break;
|
||||
case 0b10_0011:// LW(mmu);
|
||||
case 0b10_0011:// LW(bus);
|
||||
if ((SR & 0x10000) == 0)
|
||||
values = "R" + instr.rt + "[" + REG[instr.rt].ToString("x8") + "], " + instr.imm_s.ToString("x8") + "(" + REG[instr.rs].ToString("x8") + ")" + "[" + (instr.imm_s + REG[instr.rs]).ToString("x8") + "]";
|
||||
else values = "R" + instr.rt + "[" + REG[instr.rt].ToString("x8") + "], " + instr.imm_s.ToString("x8") + "(" + REG[instr.rs].ToString("x8") + ")" + "[" + (instr.imm_s + REG[instr.rs]).ToString("x8") + "]" + " WARNING IGNORED LOAD";
|
||||
output = "LW";
|
||||
break;
|
||||
case 0b10_1001:// SH(mmu);
|
||||
case 0b10_1001:// SH(bus);
|
||||
output = "SH";
|
||||
break;
|
||||
case 0b10_1010: output = "SWL"; break;
|
||||
case 0b10_0110: output = "LWR"; break;
|
||||
case 0b10_1000:// SB(mmu);
|
||||
case 0b10_1000:// SB(bus);
|
||||
output = "SB";
|
||||
break;
|
||||
case 0b10_1011:// SW(mmu);
|
||||
case 0b10_1011:// SW(bus);
|
||||
//if ((SR & 0x10000) == 0)
|
||||
// mmu.write32(REG[instr.rs] + instr.imm_s, REG[instr.rt]);
|
||||
// bus.write32(REG[instr.rs] + instr.imm_s, REG[instr.rt]);
|
||||
output = "SW";
|
||||
if ((SR & 0x10000) == 0)
|
||||
values = "R" + instr.rt + "["+REG[instr.rt].ToString("x8") + "], " + instr.imm_s.ToString("x8") + "(" + REG[instr.rs].ToString("x8") +")" + "["+ (instr.imm_s + REG[instr.rs]).ToString("x8") + "]";
|
17
ProjectPSX/Core/EX.cs
Normal file
17
ProjectPSX/Core/EX.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ProjectPSX {
|
||||
enum EX {
|
||||
LOAD_ADRESS_ERROR = 0x4,
|
||||
STORE_ADRESS_ERROR = 0x5,
|
||||
SYSCALL = 0x8,
|
||||
BREAK = 0x9,
|
||||
ILLEGAL_INSTR = 0xA,
|
||||
COPROCESSOR_ERROR = 0xB,
|
||||
OVERFLOW = 0xC
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
|||
namespace ProjectPSX {
|
||||
class ProjectPSX {
|
||||
private CPU cpu;
|
||||
private MMU mmu;
|
||||
private BUS mmu;
|
||||
|
||||
|
||||
public ProjectPSX() {
|
||||
|
@ -16,7 +16,7 @@ namespace ProjectPSX {
|
|||
|
||||
public void POWER_ON() {
|
||||
cpu = new CPU();
|
||||
mmu = new MMU();
|
||||
mmu = new BUS();
|
||||
|
||||
mmu.loadBios();
|
||||
|
26
ProjectPSX/Devices/DMA.cs
Normal file
26
ProjectPSX/Devices/DMA.cs
Normal file
|
@ -0,0 +1,26 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ProjectPSX.Devices {
|
||||
public class DMA : Device {
|
||||
|
||||
private uint CONTROL;
|
||||
private uint INTERRUPT;
|
||||
|
||||
public DMA() {
|
||||
registers = new byte[0x80];
|
||||
memOffset = 0x1F801080;
|
||||
|
||||
write32(0x1F8010F0, 0x07654321);
|
||||
}
|
||||
|
||||
public new void write32(uint addr, uint value) {
|
||||
base.write32(addr, value);
|
||||
Console.WriteLine("Write32 on DMA Address: {0} Value: {1}", addr.ToString("x8"), value.ToString("x8"));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
51
ProjectPSX/Devices/Device.cs
Normal file
51
ProjectPSX/Devices/Device.cs
Normal file
|
@ -0,0 +1,51 @@
|
|||
|
||||
namespace ProjectPSX.Devices {
|
||||
|
||||
public class Device {
|
||||
|
||||
protected byte[] registers;
|
||||
protected uint memOffset;
|
||||
|
||||
public byte load8(uint addr) {
|
||||
addr -= memOffset;
|
||||
return registers[addr];
|
||||
}
|
||||
|
||||
public ushort load16(uint addr) {
|
||||
addr -= memOffset;
|
||||
byte b0 = registers[addr + 0];
|
||||
byte b1 = registers[addr + 1];
|
||||
|
||||
return (ushort)(b1 << 8 | b0);
|
||||
}
|
||||
|
||||
public uint load32(uint addr) {
|
||||
addr -= memOffset;
|
||||
byte b0 = registers[addr + 0];
|
||||
byte b1 = registers[addr + 1];
|
||||
byte b2 = registers[addr + 2];
|
||||
byte b3 = registers[addr + 3];
|
||||
|
||||
return (uint)(b3 << 24 | b2 << 16 | b1 << 8 | b0);
|
||||
}
|
||||
|
||||
public void write8(uint addr, byte value) {
|
||||
addr -= memOffset;
|
||||
registers[addr] = value;
|
||||
}
|
||||
|
||||
public void write16(uint addr, ushort value) {
|
||||
addr -= memOffset;
|
||||
registers[addr + 0] = (byte)(value);
|
||||
registers[addr + 1] = (byte)(value >> 8);
|
||||
}
|
||||
|
||||
public void write32(uint addr, uint value) {
|
||||
addr -= memOffset;
|
||||
registers[addr + 0] = (byte)(value);
|
||||
registers[addr + 1] = (byte)(value >> 8);
|
||||
registers[addr + 2] = (byte)(value >> 16);
|
||||
registers[addr + 3] = (byte)(value >> 24);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ProjectPSX {
|
||||
static class EX {
|
||||
public const uint LOAD_ADRESS_ERROR = 0x4;
|
||||
public const uint STORE_ADRESS_ERROR = 0x5;
|
||||
public const uint SYSCALL = 0x8;
|
||||
public const uint BREAK = 0x9;
|
||||
public const uint ILLEGAL_INSTR = 0xA;
|
||||
public const uint COPROCESSOR_ERROR = 0xB;
|
||||
public const uint OVERFLOW = 0xC;
|
||||
}
|
||||
}
|
|
@ -57,10 +57,12 @@
|
|||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="PSX\EX.cs" />
|
||||
<Compile Include="PSX\CPU.cs" />
|
||||
<Compile Include="PSX\MMU.cs" />
|
||||
<Compile Include="PSX\ProjectPSX.cs" />
|
||||
<Compile Include="Devices\Device.cs" />
|
||||
<Compile Include="Devices\DMA.cs" />
|
||||
<Compile Include="Core\EX.cs" />
|
||||
<Compile Include="Core\CPU.cs" />
|
||||
<Compile Include="Core\BUS.cs" />
|
||||
<Compile Include="Core\ProjectPSX.cs" />
|
||||
<EmbeddedResource Include="Form1.resx">
|
||||
<DependentUpon>Form1.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
|
Loading…
Add table
Reference in a new issue