Skip to content

Commit aa283e0

Browse files
authored
Merge pull request #33 from schemil053/dev
Add OUTWMP and inw
2 parents 62b804d + 20b1ceb commit aa283e0

File tree

10 files changed

+164
-14
lines changed

10 files changed

+164
-14
lines changed

src/main/java/de/emilschlampp/scheCPU/compile/Compiler.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,10 @@ public byte[] compile() {
373373
outputStream.write(OUTWMP_OPCODE);
374374
FolderIOUtil.writeInt(outputStream, parseInt(cmd[1])); //Addr1
375375
FolderIOUtil.writeInt(outputStream, parseInt(cmd[2])); //Addr2
376+
} else if (cmd[0].equals("INWMP")) {
377+
outputStream.write(INWMP_OPCODE);
378+
FolderIOUtil.writeInt(outputStream, parseInt(cmd[1])); //Addr1
379+
FolderIOUtil.writeInt(outputStream, parseInt(cmd[2])); //Addr2
376380
} else if (cmd[0].equals("LOADSTRM")) {
377381
int address = parseInt(cmd[1]);
378382
String val = "";

src/main/java/de/emilschlampp/scheCPU/dissassembler/Decompiler.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,9 @@ public String decompileInstruction(Instruction instruction) {
185185
if(instruction.getOpCode() == OUTWMP_OPCODE) {
186186
line = "OUTWMP "+instruction.getAddress()+" "+instruction.getAddressS();
187187
}
188+
if(instruction.getOpCode() == INWMP_OPCODE) {
189+
line = "INWMP "+instruction.getAddress()+" "+instruction.getAddressS();
190+
}
188191
return line;
189192
}
190193

src/main/java/de/emilschlampp/scheCPU/emulator/Instruction.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ public static Instruction parse(InputStream inputStream) throws IOException {
176176
instruction.address = FolderIOUtil.readInt(inputStream);
177177
instruction.addressS = FolderIOUtil.readInt(inputStream);
178178
}
179+
if(instruction.opCode == INWMP_OPCODE) {
180+
instruction.address = FolderIOUtil.readInt(inputStream);
181+
instruction.addressS = FolderIOUtil.readInt(inputStream);
182+
}
179183

180184
return instruction;
181185
}

src/main/java/de/emilschlampp/scheCPU/emulator/ProcessorEmulator.java

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
import de.emilschlampp.scheCPU.compile.Compiler;
44
import de.emilschlampp.scheCPU.dissassembler.Decompiler;
55
import de.emilschlampp.scheCPU.util.EmulatorSandboxRestrictions;
6-
import de.emilschlampp.scheCPU.util.StaticValues;
76
import de.emilschlampp.scheCPU.util.FolderIOUtil;
8-
9-
import static de.emilschlampp.scheCPU.util.StaticValues.*;
7+
import de.emilschlampp.scheCPU.util.StaticValues;
108

119
import java.io.ByteArrayInputStream;
1210
import java.io.ByteArrayOutputStream;
1311
import java.io.IOException;
1412
import java.util.Arrays;
1513

14+
import static de.emilschlampp.scheCPU.util.StaticValues.*;
15+
1616
public class ProcessorEmulator {
1717
private final int[] memory;
1818
private final int[] io;
@@ -49,7 +49,7 @@ public ProcessorEmulator(byte[] state) {
4949
try {
5050
int version = FolderIOUtil.readInt(inputStream);
5151

52-
if(version == 1_00) {
52+
if (version == 1_00) {
5353
this.jmp = FolderIOUtil.readInt(inputStream);
5454
this.lastStoreVal = FolderIOUtil.readInt(inputStream);
5555

@@ -277,6 +277,10 @@ public void execute() {
277277
io[memory[instruction.getAddress()]] = memory[instruction.getAddressS()];
278278
jmp++;
279279
break;
280+
case INWMP_OPCODE:
281+
memory[instruction.getAddressS()] = io[memory[instruction.getAddress()]];
282+
jmp++;
283+
break;
280284
case OUTWM_OPCODE:
281285
io[instruction.getPort()] = memory[instruction.getAddress()];
282286
jmp++;
@@ -330,19 +334,19 @@ public void execute() {
330334
}
331335
break;
332336
case ADDMM_OPCODE:
333-
memory[instruction.getAddress()]+=memory[instruction.getAddressS()];
337+
memory[instruction.getAddress()] += memory[instruction.getAddressS()];
334338
jmp++;
335339
break;
336340
case SUBMM_OPCODE:
337-
memory[instruction.getAddress()]-=memory[instruction.getAddressS()];
341+
memory[instruction.getAddress()] -= memory[instruction.getAddressS()];
338342
jmp++;
339343
break;
340344
case DIVMM_OPCODE:
341-
memory[instruction.getAddress()]/=memory[instruction.getAddressS()];
345+
memory[instruction.getAddress()] /= memory[instruction.getAddressS()];
342346
jmp++;
343347
break;
344348
case MULMM_OPCODE:
345-
memory[instruction.getAddress()]*=memory[instruction.getAddressS()];
349+
memory[instruction.getAddress()] *= memory[instruction.getAddressS()];
346350
jmp++;
347351
break;
348352
case STOREREGM_OPCODE:
@@ -357,22 +361,22 @@ public void execute() {
357361
throw new RuntimeException("not implemented: " + instruction.getOpCode());
358362
}
359363

360-
if(restrictions.isAllowOutput()) {
364+
if (restrictions.isAllowOutput()) {
361365
if (io[34] != 0) {
362366
System.out.print((char) io[34]);
363367
io[34] = 0;
364368
}
365369
if (io[1] != 0) {
366370
System.out.println();
367371
System.out.println("------------------------------ [ DEBUG ] ------------------------------");
368-
System.out.println("Debug trigger triggered (IO 1), jmp="+jmp);
372+
System.out.println("Debug trigger triggered (IO 1), jmp=" + jmp);
369373
System.out.println("REG: " + Arrays.toString(register));
370374
System.out.println("MEM: " + Arrays.toString(memory));
371375

372376
Decompiler decompiler = new Decompiler(instructions);
373377

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

378382
io[1] = 0;
@@ -394,7 +398,7 @@ public void execute() {
394398
if (lastJMPBefore != io[5]) {
395399
lastJMP = io[5];
396400
}
397-
if(restrictions.isAllowReset()) {
401+
if (restrictions.isAllowReset()) {
398402
if (io[6] != 0) {
399403
jmp = 0;
400404
Arrays.fill(memory, 0);
@@ -405,7 +409,7 @@ public void execute() {
405409
}
406410

407411
public boolean fault(int errcode) {
408-
if(restrictions.isAllowFault()) {
412+
if (restrictions.isAllowFault()) {
409413
register[REGID_A] = errcode;
410414
register[REGID_B] = jmp; // tell the program where the error is
411415
jmp = io[8]; // jump to fault handler

src/main/java/de/emilschlampp/scheCPU/high/HighProgramCompiler.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,38 @@ public HighProgramCompiler compile() {
419419

420420
code = code + "\n" +
421421
"OUTWM " + port + " " + address;
422+
} else if (split[0].equals("outvar")) {
423+
String portV = split[1];
424+
String val = split[2];
425+
426+
if (!variableAddresses.containsKey(portV)) {
427+
error("variable not found!");
428+
}
429+
if (!variableAddresses.containsKey(val)) {
430+
error("variable not found!");
431+
}
432+
433+
int address1 = variableAddresses.get(portV);
434+
int address2 = variableAddresses.get(val);
435+
436+
code = code + "\n" +
437+
"OUTWMP " + address1 + " " + address2;
438+
} else if (split[0].equals("invar")) {
439+
String portV = split[1];
440+
String val = split[2];
441+
442+
if (!variableAddresses.containsKey(portV)) {
443+
error("variable not found!");
444+
}
445+
if (!variableAddresses.containsKey(val)) {
446+
error("variable not found!");
447+
}
448+
449+
int address1 = variableAddresses.get(portV);
450+
int address2 = variableAddresses.get(val);
451+
452+
code = code + "\n" +
453+
"INWMP " + address1 + " " + address2;
422454
} else if (split[0].equals("in")) {
423455
String val = split[1];
424456

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package de.emilschlampp.scheCPU.util;
2+
3+
import de.emilschlampp.scheCPU.high.processor.CompileContext;
4+
import de.emilschlampp.scheCPU.high.processor.CompileProcessor;
5+
6+
public class OCompileProcessor extends CompileProcessor {
7+
@Override
8+
public void startCompile(CompileContext compileContext) {
9+
10+
}
11+
12+
@Override
13+
public String generatePreCompileHigh() {
14+
return "";
15+
}
16+
17+
@Override
18+
public String generatePreCompileHighEnd() {
19+
return "";
20+
}
21+
22+
@Override
23+
public String generatePreCompileSCHESEM() {
24+
return "";
25+
}
26+
27+
@Override
28+
public String generateSchesemForInstruction(CompileContext compileContext, String[] instruction) {
29+
return "";
30+
}
31+
32+
@Override
33+
public String generateAfterCompileSCHESEM(CompileContext compileContext) {
34+
return "";
35+
}
36+
}

src/main/java/de/emilschlampp/scheCPU/util/StaticValues.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public class StaticValues {
4646
public static final int STOREREGM_OPCODE = 42;
4747
public static final int LOADREGM_OPCODE = 43;
4848
public static final int OUTWMP_OPCODE = 44;
49+
public static final int INWMP_OPCODE = 45;
4950

5051

5152

src/main/resources/Highlang.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Die Sprache ist wie folgt aufgebaut:
3030
| writestring | <Port> <Variable> | Gibt die angegebene Variable aus |
3131
| writestringln | <Port> <Variable> | Gibt die angegebene Variable aus und fügt ein \n hinzu |
3232
| copy | <Var1> <Var2> | Kopiert Var2 zu Var1. Funktioniert nicht bei Strings! |
33+
| outvar | <Var1> <Var2> | Gibt bei dem Port (Variable) auf var1 den wert von var2 aus |
3334

3435
Natürlich können Erweiterungen und PreCompiler die Möglichkeiten und Befehle erweitern.
3536

src/main/resources/Instructions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
| DIVMM \<ADDR\> \<PTR\> | divide memory value by PTR | |
3434
| OUTW \<PORT\> \<VAL\> | outputs val on port | |
3535
| OUTWM \<PORT\> \<ADDR\> | outputs memory value on port | |
36-
| OUTWMP \<ADDR1\> \<ADDR2\> | outputs memory value on port at addr in memory | |
36+
| OUTWMP \<ADDR1\> \<ADDR2\> | outputs memory value at addr2 on port at addr1 in memory | |
3737
| OUTWDM \<PORT\> \<PTR\> | outputs memory value at value of memory address on port | Lookup address, and outputs it |
3838
| OUTWR \<PORT\> \<REGISTER\> | outputs register value on port | |
3939
| INWM \<PORT\> \<ADDR\> | reads PORT to ADDR | |
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package de.emilschlampp.scheCPU.tests.highlang;
2+
3+
import de.emilschlampp.scheCPU.emulator.ProcessorEmulator;
4+
import de.emilschlampp.scheCPU.high.HighProgramCompiler;
5+
import de.emilschlampp.scheCPU.high.processor.CompileContext;
6+
import de.emilschlampp.scheCPU.high.processor.CompileProcessor;
7+
import de.emilschlampp.scheCPU.util.OCompileProcessor;
8+
import org.junit.jupiter.api.Assertions;
9+
import org.junit.jupiter.api.Test;
10+
11+
import java.util.Arrays;
12+
import java.util.HashMap;
13+
import java.util.Map;
14+
15+
public class HighlangIOVarTest {
16+
@Test
17+
public void testHighlangOutVarFunction() {
18+
HighProgramCompiler compiler = new HighProgramCompiler(
19+
"reserve port 1\nreserve value 1\n" +
20+
"var port 129\n" +
21+
"var value 15\n" +
22+
"outvar port value"
23+
);
24+
25+
ProcessorEmulator emulator = new ProcessorEmulator(128, 128, compiler.toBytecode());
26+
27+
int c = 0;
28+
while (emulator.canExecute()) {
29+
c++;
30+
Assertions.assertTrue(c < 1000, "Too many iterations!");
31+
32+
emulator.execute();
33+
}
34+
35+
Assertions.assertEquals(15, emulator.getIo()[129]);
36+
37+
}
38+
39+
@Test
40+
public void testHighlangInVarFunction() {
41+
HighProgramCompiler compiler = new HighProgramCompiler(
42+
"reserve port 1\nreserve port2 1\nreserve value 1\n" +
43+
"var port 129\n" +
44+
"var port2 130\n" +
45+
"var value 15\n" +
46+
"invar port value\n"+
47+
"outvar port2 value"
48+
);
49+
50+
ProcessorEmulator emulator = new ProcessorEmulator(128, 128, compiler.toBytecode());
51+
52+
emulator.getIo()[129] = 32;
53+
54+
int c = 0;
55+
while (emulator.canExecute()) {
56+
c++;
57+
Assertions.assertTrue(c < 1000, "Too many iterations!");
58+
59+
emulator.execute();
60+
}
61+
62+
Assertions.assertEquals(32, emulator.getIo()[130]);
63+
64+
}
65+
}

0 commit comments

Comments
 (0)