CPU Commit (WIP)

This commit is contained in:
Rodolphe de Saint Léger 2025-05-13 10:03:25 +02:00
parent 4abd895f87
commit b016a8fd9e
15 changed files with 18928 additions and 36 deletions

40
.gitignore vendored
View file

@ -1,50 +1,18 @@
# These are some examples of commonly ignored file patterns.
# You should customize this list as applicable to your project.
# Learn more about .gitignore:
# https://www.atlassian.com/git/tutorials/saving-changes/gitignore
# Node artifact files
node_modules/
dist/
# Compiled Java class files
*.class
# Compiled Python bytecode
*.py[cod]
# Log files
*.log
# Package files
*.jar
# Maven
target/
dist/
# JetBrains IDE
.idea/
# Unit test reports
TEST*.xml
# Generated by MacOS
.DS_Store
# Generated by Windows
Thumbs.db
# Applications
*.app
*.exe
*.war
# Large media files
*.mp4
*.tiff
*.avi
*.flv
*.mov
*.wmv
.classpath
.settings
.project
/target/

14
miggy-emu/Changes.md Normal file
View file

@ -0,0 +1,14 @@
**This is a 68010 emulator**
This implementation focus on being binary compatible with code written by the 68010, adding additional features on unused bits. Care has been taken about to have same behaviour when not using/enabling additional features.
*The following changes are applied*
- flow trace mode is available (bit 14 in SR)
- interrupt/master supervisor is available (bit 12 in SR)
- 68020 effective addressing modes bits are available in the extension word.
- 68020 additional instructions are available.
- bra/bcc/bsr can use 32 bits displacement
- exception stack frame $2000 can be enabled using a specific bit in SSWI
- 32 bits access can be recovered using specific bits in SSW (will use 16 bits by default)

19
miggy-emu/pom.xml Normal file
View file

@ -0,0 +1,19 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>miggy</groupId>
<artifactId>miggy-root</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>miggy-emu</groupId>
<artifactId>miggy-emu</artifactId>
<dependencies>
<dependency>
<groupId>com.squareup</groupId>
<artifactId>javapoet</artifactId>
<version>1.13.0</version>
</dependency>
</dependencies>
</project>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,71 @@
package miggy.cpu.genpoet;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import miggy.cpupoet.MacroPLA;
public class CoreVerifier {
public static final Pattern OP_PATTERN2 = Pattern.compile("^(\\S+)\\s+(\\S+)\\s+([\\S.]+)\\s+([\\S.]+)\\s+(\\S+).*");
public static void main(String[] args) throws NumberFormatException, IOException {
InputStream res = CoreVerifier.class.getResourceAsStream("m68000.lst");
BufferedReader in = new BufferedReader(new InputStreamReader(res, StandardCharsets.UTF_8));
try {
String line = null;
while((line = in.readLine()) != null) {
Matcher matcher = OP_PATTERN2.matcher(line);
if (matcher.find()) {
String opname = matcher.group(3);
int opcode = Integer.parseInt(matcher.group(1), 16);
int mask = Integer.parseInt(matcher.group(2), 16);
String ea1 = matcher.group(4);
String ea2 = matcher.group(5);
StringBuilder builder = new StringBuilder();
builder.append(opname.replace('.', '_'));
if (!"-".equals(ea1)) {
builder.append('_');
builder.append(ea1);
}
if (!"-".equals(ea2)) {
builder.append('_');
builder.append(ea2);
}
String mnemonic = builder.toString();
boolean found = false;
for(MacroPLA entry : MacroPLA.values()) {
if ((opcode == entry.opcode) && (mask == entry.opmask)) {
found = true;
if (!mnemonic.equals(entry.name())) {
System.out.println(String.format("mismatch for opcode 0x%04x (mask: 0x%04x) want '%s', got '%s'", opcode, mask, mnemonic, entry.name()));
}
break;
}
}
if (!found) {
System.out.println(String.format("opcode '%s' 0x%04x (mask: 0x%04x) not found", mnemonic, opcode, mask));
}
}
}
} finally {
in.close();
}
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,242 @@
package miggy.cpupoet;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.HashSet;
import java.util.Set;
public class CoreTest extends Core {
private final ByteBuffer memory;
private final Set<Integer> berrs = new HashSet<Integer>();
public static void main(String[] args) {
ResetTest test2 = new ResetTest();
test2.testReset();
CoreTest test = new CoreTest();
int pc = test.memory.capacity() - 0x800;
test.setInitialSSP(0x040000);
test.setInitialPC(pc);
test.write16(pc, 0x4848);
test.write16(pc + 2, 0x0200);
test.write16(pc + 4, 0x1234);
test.write16(pc + 6, 0x4849);
test.write32(4 << 2, 0x090000);
//test.setclrSSWI(SSWI_XTRP | SSWI_XBRK, 0);
test.execute(Integer.MAX_VALUE);
test.execute(Integer.MAX_VALUE);
test.execute(Integer.MAX_VALUE);
}
public CoreTest() {
/* allocate 512 MiB */
this.memory = ByteBuffer.allocate(512 * 1024);
memory.order(ByteOrder.BIG_ENDIAN);
}
public void setInitialSSP(int ssp) {
write32(0, ssp);
}
public void setInitialPC(int ssp) {
write32(4, ssp);
}
public Set<Integer> getBErrs() {
return berrs;
}
@Override
public int fetch16(int aob) {
return read16(aob);
}
@Override
public int fetch32(int aob) {
return read32(aob);
}
protected int check8(int aob) {
if (((aob & 0x7fffffff) + 1 >= memory.capacity()) || berrs.contains(aob)) {
setclrSSW(SSW_BR, 0);
return -1;
}
return aob;
}
protected int check16(int aob) {
if ((aob &= 0x7fffffff) + 2 >= memory.capacity() || berrs.contains(aob)) {
setclrSSW(SSW_BR, 0);
return -1;
}
return aob;
}
protected int check32(int aob) {
if ((aob &= 0x7fffffff) + 4 >= memory.capacity() || berrs.contains(aob)) {
setclrSSW(SSW_BR, 0);
return -1;
}
return aob;
}
@Override
public byte read8(int aob) {
aob = check8(aob);
return aob < 0 ? 0 : memory.get(aob);
}
@Override
public short read16(int aob) {
aob = check16(aob);
return aob < 0 ? 0 : memory.getShort(aob);
}
@Override
public int read32(int aob) {
aob = check32(aob);
return aob < 0 ? 0 : memory.getInt(aob);
}
@Override
public void write8(int aob, int dob) {
aob = check8(aob);
if (aob >= 0) {
memory.put(aob, (byte) dob);
}
}
@Override
public void write16(int aob, int dob) {
aob = check16(aob);
if (aob >= 0) {
memory.putShort(aob, (short) dob);
}
}
@Override
public void write32(int aob, int dob) {
aob = check32(aob);
if (aob >= 0) {
memory.putInt(aob, dob);
}
}
@Override
public int handle_interrupt(int level) {
return IRQ_AVEC;
}
@Override
public int handle_bkpt(int pc, int data) {
return BKPT_RPIR | BKPT_EXIT | 0x4e71;
}
public int getPC() {
return pc;
}
public void setPC(int pc) {
this.pc = pc;
}
public int getScan() {
return scan;
}
public void setScan(int scan) {
this.scan = scan;
}
public int getAluB() {
return alub;
}
public void setAluB(int alub) {
this.alub = alub;
}
public int getIRB() {
return irb;
}
public void setIRB(int irb) {
this.irb = irb;
}
public int getIR() {
return ir;
}
public void setIR(int ir) {
this.ir = ir;
}
public int getMPC() {
return mpc;
}
public void setMPC(int mpc) {
this.mpc = mpc;
}
public int getCIP() {
return cip;
}
public void setCIP(int cip) {
this.cip = cip;
}
public int getAU() {
return au;
}
public void setAU(int au) {
this.au = au;
}
public int getAT() {
return at;
}
public void setAT(int at) {
this.at = at;
}
public int getDT() {
return dt;
}
public void setDT(int dt) {
this.dt = dt;
}
public int getSlice() {
return slice;
}
public void setSlice(int slice) {
this.slice = slice;
}
}

View file

@ -0,0 +1,57 @@
package miggy.cpupoet;
import junit.framework.TestCase;
public class ResetTest extends TestCase {
public void testReset() {
CoreTest core = new CoreTest();
core.setInitialSSP(0x4000);
core.setInitialPC(0x8000);
core.write16(0x8000, 0x4849);
core.getBErrs().add(0);
core.getBErrs().add(4);
core.getBErrs().add(0x8000);
core.execute(50);
assertTrue(core.getISP() != 0x4000); // isp did not fetch because of bus err
assertTrue(core.getPC() != 0x8000);
assertEquals(CoreALU.SSWI_DERR, core.getSSWI() & CoreALU.SSWI_DERR);
core.getBErrs().remove(0);
core.execute(50);
assertTrue(core.getISP() != 0x4000); // still not fetched because CPU is stuck on dbrr
assertTrue(core.getPC() != 0x8000);
assertEquals(CoreALU.SSWI_DERR, core.getSSWI() & CoreALU.SSWI_DERR);
core.pulse_reset(); // now pulse reset signal
core.execute(50);
assertTrue(core.getISP() == 0x4000); // isp fetched
assertTrue(core.getPC() != 0x8000); // but not PC
assertEquals(CoreALU.SSWI_DERR, core.getSSWI() & CoreALU.SSWI_DERR);
core.pulse_reset(); // pulse reset signal again
core.getBErrs().remove(4); // unlock pc
core.execute(50);
// now both fetched, but still stuck to dbrr because prefetch of irb failed
assertTrue(core.getISP() == 0x4000);
assertTrue(core.getPC() == 0x8000);
assertEquals(CoreALU.SSWI_DERR, core.getSSWI() & CoreALU.SSWI_DERR);
core.getBErrs().remove(0x8000);
core.pulse_reset();
core.execute(50);
// we did exit because of breackpoint
assertTrue(core.getISP() == 0x4000);
assertTrue(core.getCIP() == 0x8000);
assertTrue(core.getPC() == 0x8002);
assertEquals(0, core.getSSWI() & CoreALU.SSWI_DERR);
}
}

34
miggy-export/pom.xml Normal file
View file

@ -0,0 +1,34 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>miggy</groupId>
<artifactId>miggy-root</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>miggy-export</groupId>
<artifactId>miggy-export</artifactId>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>true</appendAssemblyId>
<descriptors>
<descriptor>src/main/assembly/full.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,33 @@
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<id>full</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.basedir}/..</directory>
<outputDirectory>${project.parent.name}</outputDirectory>
<excludes>
<exclude>.DS_Store</exclude>
<exclude>.project</exclude>
<exclude>.pydevproject</exclude>
<exclude>.classpath</exclude>
<exclude>.settings/**</exclude>
<exclude>target/**</exclude>
<exclude>*/.DS_Store</exclude>
<exclude>*/.project</exclude>
<exclude>*/.pydevproject</exclude>
<exclude>*/.classpath</exclude>
<exclude>*/.settings/**</exclude>
<exclude>*/target/**</exclude>
</excludes>
</fileSet>
</fileSets>
</assembly>

24
pom.xml Normal file
View file

@ -0,0 +1,24 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>miggy</groupId>
<artifactId>miggy-root</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>miggy-emu</module>
<module>miggy-export</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>