Skip to content

Commit

Permalink
Merge pull request #25 from schemil053/dev
Browse files Browse the repository at this point in the history
A little update
  • Loading branch information
schemil053 authored Jan 31, 2025
2 parents 71fea63 + c0f0d39 commit efc28c2
Show file tree
Hide file tree
Showing 17 changed files with 549 additions and 265 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,7 @@ build/
.vscode/

### Mac OS ###
.DS_Store
.DS_Store

# Compile files
compile.sbin
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ This emulator runs in a "locked-down" mode: programs are loaded at compile-time,
### Registers
- The CPU has 5 registers:
- A, B, C, D: currently unused (highlang uses them, but I want to add more functions that rely on them in the future)
- BOOL: The bool register stores the result of the last operation
- BOOL: The bool register stores the result of the last boolean-resulting operation

### Memory management
- The memory management in this emulator is simplified but includes a distinct separation between program instructions and data.
Expand Down Expand Up @@ -155,7 +155,7 @@ mvn install
</dependency>
```

[## Programming Languages
## Programming Languages
There are 2 Languages that this default configuration can compile and understand.
The first one is Schessembler. It's an assembly-like language with a custom instruction set.
The second one is Highlang. It converts to Schessembler, wich converts to bytecode.
Expand All @@ -172,7 +172,7 @@ Structure
```text
command <arg1> <arg2> <arg...>...
```
You can find all available Instructions [here](src/main/resources/Highlang.md)]()
You can find all available Instructions [here](src/main/resources/Highlang.md)

## Examples
### Schessembler Examples
Expand Down
2 changes: 1 addition & 1 deletion README_DE.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Dieser Emulator läuft im "locked-down"-Modus: Programme werden beim Start in ei
### Register
- Die CPU hat 5 Register:
- A, B, C, D: derzeit unbenutzt (highlang verwendet sie, aber ich möchte in Zukunft weitere Funktionen hinzufügen, die auf ihnen basieren).
- BOOL: Das BOOL-Register speichert das Ergebnis der letzten Operation.
- BOOL: Das BOOL-Register speichert das Ergebnis der letzten boolean-zurückgebenden Operation.

### Speicherverwaltung
- Die Speicherverwaltung in diesem Emulator ist vereinfacht und umfasst eine klare Trennung zwischen Programmcode und Daten.
Expand Down
212 changes: 127 additions & 85 deletions src/main/java/de/emilschlampp/scheCPU/compile/Compiler.java

Large diffs are not rendered by default.

251 changes: 141 additions & 110 deletions src/main/java/de/emilschlampp/scheCPU/dissassembler/Decompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,116 +35,7 @@ public String decompile() {
String pr = "";

for (Instruction instruction : instructions) {
String line = "";

if(instruction.getOpCode() == JMP_OPCODE) {
line = "JMP "+instruction.getAddress();
}
if(instruction.getOpCode() == LOAD_OPCODE) {
line = "LOAD "+fromRegID(instruction.getRegisterID())+" "+instruction.getValue();
}
if(instruction.getOpCode() == LOADMEM_OPCODE) {
line = "LOADMEM "+fromRegID(instruction.getRegisterID())+" "+instruction.getAddress();
}
if(instruction.getOpCode() == STORE_OPCODE) {
line = "STORE "+fromRegID(instruction.getRegisterID())+" "+instruction.getAddress();
}
if(instruction.getOpCode() == STOREREG_OPCODE) {
line = "STOREREG "+instruction.getAddress()+" "+fromRegID(instruction.getRegisterID());
}
if(instruction.getOpCode() == CMPM_OPCODE) {
line = "CMPM "+fromRegID(instruction.getRegisterID())+" "+instruction.getAddress();
}
if(instruction.getOpCode() == CMPMEM_OPCODE) {
line = "CMPMEM "+instruction.getAddress()+" "+instruction.getAddressS();
}
if(instruction.getOpCode() == CMPR_OPCODE) {
line = "CMPR "+fromRegID(instruction.getRegisterID())+" "+fromRegID(instruction.getRegisterIDS());
}
if(instruction.getOpCode() == CMPMC_OPCODE) {
line = "CMPMC "+fromRegID(instruction.getRegisterID());
}
if(instruction.getOpCode() == STOREMEM_OPCODE) {
line = "STOREMEM "+instruction.getAddress()+" "+instruction.getValue();
}
if(instruction.getOpCode() == CJMP_OPCODE) {
line = "CJMP "+instruction.getAddress();
}
if(instruction.getOpCode() == ADD_OPCODE) {
line = "ADD "+fromRegID(instruction.getRegisterID())+" "+instruction.getValue();
}
if(instruction.getOpCode() == ADDM_OPCODE) {
line = "ADDM "+instruction.getAddress()+" "+instruction.getValue();
}
if(instruction.getOpCode() == ADDR_OPCODE) {
line = "ADDR "+fromRegID(instruction.getRegisterID())+" "+fromRegID(instruction.getRegisterIDS());
}
if(instruction.getOpCode() == COPYR_OPCODE) {
line = "COPYR "+fromRegID(instruction.getRegisterID())+" "+fromRegID(instruction.getRegisterIDS());
}
if(instruction.getOpCode() == SUB_OPCODE) {
line = "SUB "+fromRegID(instruction.getRegisterID())+" "+instruction.getValue();
}
if(instruction.getOpCode() == SUBM_OPCODE) {
line = "SUBM "+instruction.getAddress()+" "+instruction.getValue();
}
if(instruction.getOpCode() == MUL_OPCODE) {
line = "MUL "+fromRegID(instruction.getRegisterID())+" "+instruction.getValue();
}
if(instruction.getOpCode() == MULM_OPCODE) {
line = "MULM "+instruction.getAddress()+" "+instruction.getValue();
}
if(instruction.getOpCode() == DIV_OPCODE) {
line = "DIV "+fromRegID(instruction.getRegisterID())+" "+instruction.getValue();
}
if(instruction.getOpCode() == DIVM_OPCODE) {
line = "DIVM "+instruction.getAddress()+" "+instruction.getValue();
}
if(instruction.getOpCode() == OUTW_OPCODE) {
line = "OUTW "+instruction.getPort()+" "+instruction.getValue();
}
if(instruction.getOpCode() == OUTWM_OPCODE) {
line = "OUTWM "+instruction.getPort()+" "+instruction.getAddress();
}
if(instruction.getOpCode() == OUTWDM_OPCODE) {
line = "OUTWDM "+instruction.getPort()+" "+instruction.getAddress();
}
if(instruction.getOpCode() == OUTWR_OPCODE) {
line = "OUTWR "+instruction.getPort()+" "+fromRegID(instruction.getRegisterID());
}
if(instruction.getOpCode() == INWM_OPCODE) {
line = "INWM "+instruction.getPort()+" "+instruction.getAddress();
}
if(instruction.getOpCode() == INWDM_OPCODE) {
line = "INWDM "+instruction.getPort()+" "+instruction.getAddress();
}
if(instruction.getOpCode() == INWR_OPCODE) {
line = "INWR "+instruction.getPort()+" "+fromRegID(instruction.getRegisterID());
}
if(instruction.getOpCode() == CNJMP_OPCODE) {
line = "CNJMP "+instruction.getAddress();
}
if(instruction.getOpCode() == CZJMP_OPCODE) {
line = "CZJMP "+instruction.getAddress();
}
if(instruction.getOpCode() == BJMP_OPCODE) {
line = "BJMP";
}
if(instruction.getOpCode() == MJMP_OPCODE) {
line = "MJMP "+instruction.getAddress();
}
if(instruction.getOpCode() == CMJMP_OPCODE) {
line = "CMJMP "+instruction.getAddress();
}
if(instruction.getOpCode() == CNMJMP_OPCODE) {
line = "CNMJMP "+instruction.getAddress();
}
if(instruction.getOpCode() == CZMJMP_OPCODE) {
line = "CZMJMP "+instruction.getAddress();
}


pr+="\n"+line;
pr+="\n"+decompileInstruction(instruction);
}

if(!pr.isEmpty()) {
Expand All @@ -154,6 +45,146 @@ public String decompile() {
return pr;
}

public String decompileInstruction(int index) {
return decompileInstruction(instructions[index]);
}

public String decompileInstructionSave(int index) {
if(index >= instructions.length || index < 0) {
return null;
}
return decompileInstruction(index);
}

public String decompileInstruction(Instruction instruction) {
String line = "";

if(instruction.getOpCode() == JMP_OPCODE) {
line = "JMP "+instruction.getAddress();
}
if(instruction.getOpCode() == LOAD_OPCODE) {
line = "LOAD "+fromRegID(instruction.getRegisterID())+" "+instruction.getValue();
}
if(instruction.getOpCode() == LOADMEM_OPCODE) {
line = "LOADMEM "+fromRegID(instruction.getRegisterID())+" "+instruction.getAddress();
}
if(instruction.getOpCode() == STORE_OPCODE) {
line = "STORE "+fromRegID(instruction.getRegisterID())+" "+instruction.getAddress();
}
if(instruction.getOpCode() == STOREREG_OPCODE) {
line = "STOREREG "+instruction.getAddress()+" "+fromRegID(instruction.getRegisterID());
}
if(instruction.getOpCode() == STOREREGM_OPCODE) {
line = "STOREREGM "+instruction.getAddress()+" "+fromRegID(instruction.getRegisterID());
}
if(instruction.getOpCode() == LOADREGM_OPCODE) {
line = "STOREREGM "+fromRegID(instruction.getRegisterID())+ " " +instruction.getAddress();
}
if(instruction.getOpCode() == CMPM_OPCODE) {
line = "CMPM "+fromRegID(instruction.getRegisterID())+" "+instruction.getAddress();
}
if(instruction.getOpCode() == CMPMEM_OPCODE) {
line = "CMPMEM "+instruction.getAddress()+" "+instruction.getAddressS();
}
if(instruction.getOpCode() == CMPR_OPCODE) {
line = "CMPR "+fromRegID(instruction.getRegisterID())+" "+fromRegID(instruction.getRegisterIDS());
}
if(instruction.getOpCode() == CMPMC_OPCODE) {
line = "CMPMC "+fromRegID(instruction.getRegisterID());
}
if(instruction.getOpCode() == STOREMEM_OPCODE) {
line = "STOREMEM "+instruction.getAddress()+" "+instruction.getValue();
}
if(instruction.getOpCode() == CJMP_OPCODE) {
line = "CJMP "+instruction.getAddress();
}
if(instruction.getOpCode() == ADD_OPCODE) {
line = "ADD "+fromRegID(instruction.getRegisterID())+" "+instruction.getValue();
}
if(instruction.getOpCode() == ADDM_OPCODE) {
line = "ADDM "+instruction.getAddress()+" "+instruction.getValue();
}
if(instruction.getOpCode() == ADDR_OPCODE) {
line = "ADDR "+fromRegID(instruction.getRegisterID())+" "+fromRegID(instruction.getRegisterIDS());
}
if(instruction.getOpCode() == COPYR_OPCODE) {
line = "COPYR "+fromRegID(instruction.getRegisterID())+" "+fromRegID(instruction.getRegisterIDS());
}
if(instruction.getOpCode() == SUB_OPCODE) {
line = "SUB "+fromRegID(instruction.getRegisterID())+" "+instruction.getValue();
}
if(instruction.getOpCode() == SUBM_OPCODE) {
line = "SUBM "+instruction.getAddress()+" "+instruction.getValue();
}
if(instruction.getOpCode() == MUL_OPCODE) {
line = "MUL "+fromRegID(instruction.getRegisterID())+" "+instruction.getValue();
}
if(instruction.getOpCode() == MULM_OPCODE) {
line = "MULM "+instruction.getAddress()+" "+instruction.getValue();
}
if(instruction.getOpCode() == DIV_OPCODE) {
line = "DIV "+fromRegID(instruction.getRegisterID())+" "+instruction.getValue();
}
if(instruction.getOpCode() == DIVM_OPCODE) {
line = "DIVM "+instruction.getAddress()+" "+instruction.getValue();
}
if(instruction.getOpCode() == OUTW_OPCODE) {
line = "OUTW "+instruction.getPort()+" "+instruction.getValue();
}
if(instruction.getOpCode() == OUTWM_OPCODE) {
line = "OUTWM "+instruction.getPort()+" "+instruction.getAddress();
}
if(instruction.getOpCode() == OUTWDM_OPCODE) {
line = "OUTWDM "+instruction.getPort()+" "+instruction.getAddress();
}
if(instruction.getOpCode() == OUTWR_OPCODE) {
line = "OUTWR "+instruction.getPort()+" "+fromRegID(instruction.getRegisterID());
}
if(instruction.getOpCode() == INWM_OPCODE) {
line = "INWM "+instruction.getPort()+" "+instruction.getAddress();
}
if(instruction.getOpCode() == INWDM_OPCODE) {
line = "INWDM "+instruction.getPort()+" "+instruction.getAddress();
}
if(instruction.getOpCode() == INWR_OPCODE) {
line = "INWR "+instruction.getPort()+" "+fromRegID(instruction.getRegisterID());
}
if(instruction.getOpCode() == CNJMP_OPCODE) {
line = "CNJMP "+instruction.getAddress();
}
if(instruction.getOpCode() == CZJMP_OPCODE) {
line = "CZJMP "+instruction.getAddress();
}
if(instruction.getOpCode() == BJMP_OPCODE) {
line = "BJMP";
}
if(instruction.getOpCode() == MJMP_OPCODE) {
line = "MJMP "+instruction.getAddress();
}
if(instruction.getOpCode() == CMJMP_OPCODE) {
line = "CMJMP "+instruction.getAddress();
}
if(instruction.getOpCode() == CNMJMP_OPCODE) {
line = "CNMJMP "+instruction.getAddress();
}
if(instruction.getOpCode() == CZMJMP_OPCODE) {
line = "CZMJMP "+instruction.getAddress();
}
if(instruction.getOpCode() == ADDMM_OPCODE) {
line = "ADDMM "+instruction.getAddress()+" "+instruction.getAddressS();
}
if(instruction.getOpCode() == SUBMM_OPCODE) {
line = "SUBMM "+instruction.getAddress()+" "+instruction.getAddressS();
}
if(instruction.getOpCode() == DIVMM_OPCODE) {
line = "DIVMM "+instruction.getAddress()+" "+instruction.getAddressS();
}
if(instruction.getOpCode() == MULMM_OPCODE) {
line = "MULMM "+instruction.getAddress()+" "+instruction.getAddressS();
}
return line;
}

public Instruction[] getInstructions() {
return instructions;
}
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/de/emilschlampp/scheCPU/emulator/Instruction.java
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,30 @@ public static Instruction parse(InputStream inputStream) throws IOException {
if(instruction.opCode == CZMJMP_OPCODE) {
instruction.address = FolderIOUtil.readInt(inputStream);
}
if(instruction.opCode == ADDMM_OPCODE) {
instruction.address = FolderIOUtil.readInt(inputStream);
instruction.addressS = FolderIOUtil.readInt(inputStream);
}
if(instruction.opCode == SUBMM_OPCODE) {
instruction.address = FolderIOUtil.readInt(inputStream);
instruction.addressS = FolderIOUtil.readInt(inputStream);
}
if(instruction.opCode == DIVMM_OPCODE) {
instruction.address = FolderIOUtil.readInt(inputStream);
instruction.addressS = FolderIOUtil.readInt(inputStream);
}
if(instruction.opCode == MULMM_OPCODE) {
instruction.address = FolderIOUtil.readInt(inputStream);
instruction.addressS = FolderIOUtil.readInt(inputStream);
}
if(instruction.opCode == STOREREGM_OPCODE) {
instruction.address = FolderIOUtil.readInt(inputStream);
instruction.registerID = inputStream.read();
}
if(instruction.opCode == LOADREGM_OPCODE) {
instruction.registerID = inputStream.read();
instruction.address = FolderIOUtil.readInt(inputStream);
}

return instruction;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,30 @@ public void execute() {
jmp++;
}
break;
case ADDMM_OPCODE:
memory[instruction.getAddress()]+=memory[instruction.getAddressS()];
jmp++;
break;
case SUBMM_OPCODE:
memory[instruction.getAddress()]-=memory[instruction.getAddressS()];
jmp++;
break;
case DIVMM_OPCODE:
memory[instruction.getAddress()]/=memory[instruction.getAddressS()];
jmp++;
break;
case MULMM_OPCODE:
memory[instruction.getAddress()]*=memory[instruction.getAddressS()];
jmp++;
break;
case STOREREGM_OPCODE:
register[instruction.getRegisterID()] = memory[memory[instruction.getAddress()]];
jmp++;
break;
case LOADREGM_OPCODE:
memory[memory[instruction.getAddress()]] = register[instruction.getRegisterID()];
jmp++;
break;
default:
throw new RuntimeException("not implemented: " + instruction.getOpCode());
}
Expand All @@ -335,8 +359,18 @@ public void execute() {
io[34] = 0;
}
if (io[1] != 0) {
System.out.println();
System.out.println("------------------------------ [ DEBUG ] ------------------------------");
System.out.println("Debug trigger triggered (IO 1), jmp="+jmp);
System.out.println("REG: " + Arrays.toString(register));
System.out.println("MEM: " + Arrays.toString(memory));

Decompiler decompiler = new Decompiler(instructions);

for (int i = -3; i <= 3; i++) {
System.out.println((i == 0 ? "-> " : " ") + (jmp+i) + " " + decompiler.decompileInstruction(jmp+i));
}

io[1] = 0;
}
if (io[2] != 0) {
Expand Down
Loading

0 comments on commit efc28c2

Please sign in to comment.