Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Jessica Hawkwell
/
kcpu
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
2
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit 78af4d11
authored
Oct 01, 2017
by
Jessica Hawkwell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
started preliminary support for interrupts, stacks, and function calls
1 parent
c44caf9d
Pipeline
#211
passed
in 1 minute 8 seconds
Changes
21
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
507 additions
and
275 deletions
.gitignore
src/main/java/me/felinewith/kcpu/KBoard.java
src/main/java/me/felinewith/kcpu/Kasm.java
src/main/java/me/felinewith/kcpu/Kcpu.java
src/main/java/me/felinewith/kcpu/Kemulator.java
src/main/java/me/felinewith/kcpu/hardware/Kmcu.java
src/main/java/me/felinewith/kcpu/interfaces/IDevice.java
src/main/java/me/felinewith/kcpu/interfaces/IMemory.java
src/main/java/me/felinewith/kcpu/memory/BootRom.java
src/main/java/me/felinewith/kcpu/memory/Buffer.java
src/main/java/me/felinewith/kcpu/opcodes/Memory.java
src/main/java/me/felinewith/kcpu/opcodes/OpDirector.java
src/main/java/me/felinewith/kcpu/util/BaseDevice.java
src/main/java/me/felinewith/kcpu/util/BaseMemory.java
src/main/java/me/felinewith/kcpu/util/CPUStoppedException.java
src/main/java/me/felinewith/kcpu/util/HardwareExec.java
src/main/java/me/felinewith/kcpu/util/HardwareMemIrq.java
src/main/java/me/felinewith/kcpu/util/HardwareSendIrq.java → src/main/java/me/felinewith/kcpu/util/HardwareRecvIrq.java
src/main/java/me/felinewith/kcpu/util/helpers/ValueHelper.java
src/main/java/me/felinewith/kcpu/util/helpers/ValueType.java
test.kasm
.gitignore
View file @
78af4d1
# project-specific stuffs
# project-specific stuffs
*.mem
*.mem
.txt
*.bin
*.bin
*.kc
*.kc
...
...
src/main/java/me/felinewith/kcpu/KBoard.java
View file @
78af4d1
...
@@ -13,8 +13,9 @@ import me.felinewith.kcpu.hardware.Kmcu;
...
@@ -13,8 +13,9 @@ import me.felinewith.kcpu.hardware.Kmcu;
import
me.felinewith.kcpu.interfaces.IDevice
;
import
me.felinewith.kcpu.interfaces.IDevice
;
import
me.felinewith.kcpu.interfaces.IMemory
;
import
me.felinewith.kcpu.interfaces.IMemory
;
import
me.felinewith.kcpu.util.BaseDevice
;
import
me.felinewith.kcpu.util.BaseDevice
;
import
me.felinewith.kcpu.util.
HardwareExec
;
import
me.felinewith.kcpu.util.
CPUStoppedException
;
import
me.felinewith.kcpu.util.HardwareMemIrq
;
import
me.felinewith.kcpu.util.HardwareMemIrq
;
import
me.felinewith.kcpu.util.HardwareRecvIrq
;
/**
/**
*
*
...
@@ -56,45 +57,66 @@ public class KBoard extends BaseDevice implements IMemory {
...
@@ -56,45 +57,66 @@ public class KBoard extends BaseDevice implements IMemory {
System
.
out
.
println
(
"CPU up..."
);
System
.
out
.
println
(
"CPU up..."
);
while
(
cpu
.
workCycle
()
!=
0xff
)
{
try
{
Thread
.
yield
();
while
(
true
)
{
cpu
.
workCycle
();
Thread
.
yield
();
}
}
}
catch
(
CPUStoppedException
x
)
{}
System
.
err
.
println
(
"CPU Stopped [zpwr]"
);
System
.
err
.
println
(
"CPU Stopped [zpwr]"
);
tpe
.
shutdown
();
tpe
.
shutdown
();
System
.
err
.
println
(
"Timers stopped"
);
int
a
;
int
a
;
for
(
a
=
0
;
a
<=
0xf
;
a
++)
{
for
(
a
=
0
;
a
<=
0xf
;
a
++)
{
if
(
devices
[
a
]
!=
null
)
{
if
(
devices
[
a
]
!=
null
)
{
devices
[
a
].
powerOff
();
devices
[
a
].
powerOff
();
System
.
err
.
println
(
String
.
format
(
"device %x stopped"
,
a
));
}
}
if
(
memDevs
[
a
]
!=
null
)
{
if
(
memDevs
[
a
]
!=
null
)
{
memDevs
[
a
].
powerOff
();
memDevs
[
a
].
powerOff
();
System
.
err
.
println
(
String
.
format
(
"memdev %x stopped"
,
a
));
}
}
}
}
dumpEverything
();
dumpEverything
();
}
}
@Override
public
void
memIrq
(
short
addr
)
{
@Override
public
void
memIrq
(
short
addr
,
byte
irq
)
{
short
dev
=
checkDevice
(
addr
);
short
dev
=
checkDevice
(
addr
);
short
rdev
=
(
short
)(
0x0f
&
dev
);
short
rdev
=
(
short
)(
0x0f
&
dev
);
if
(
dev
==
0x7f
)
{
devices
[
0
].
memIrq
(
addr
);
}
StackTraceElement
ste
=
Thread
.
currentThread
().
getStackTrace
()[
1
];
String
className
=
ste
.
getClassName
();
int
sendIrq
=
16
;
int
a
;
for
(
a
=
0
;
a
<
16
;
a
++)
{
if
(
devices
[
a
].
getClass
().
getCanonicalName
().
equals
(
className
))
{
sendIrq
=
a
;
break
;
}
}
if
(
dev
==
0x7f
)
{
devices
[
0
].
memIrq
(
addr
,
(
byte
)
sendIrq
);
}
else
if
(
dev
<=
0x0f
)
{
else
if
(
dev
<=
0x0f
)
{
short
devOff
=
deviceMaps
[
rdev
].
getOffset
();
short
devOff
=
deviceMaps
[
rdev
].
getOffset
();
short
devAddr
=
(
short
)(
addr
-
devOff
);
short
devAddr
=
(
short
)(
addr
-
devOff
);
tpe
.
execute
(
new
HardwareMemIrq
(
devices
[
rdev
],
devAddr
));
tpe
.
execute
(
new
HardwareMemIrq
(
devices
[
rdev
],
devAddr
,
(
byte
)
sendIrq
));
}
}
else
if
(
0x10
<=
dev
&&
dev
<=
0x1f
)
{
else
if
(
0x10
<=
dev
&&
dev
<=
0x1f
)
{
short
devOff
=
memDevMaps
[
rdev
].
getOffset
();
short
devOff
=
memDevMaps
[
rdev
].
getOffset
();
short
devAddr
=
(
short
)(
addr
-
devOff
);
short
devAddr
=
(
short
)(
addr
-
devOff
);
tpe
.
execute
(
new
HardwareMemIrq
(
memDevs
[
rdev
],
devAddr
));
tpe
.
execute
(
new
HardwareMemIrq
(
memDevs
[
rdev
],
devAddr
,
(
byte
)
sendIrq
));
}
}
}
}
@Override
public
void
sendIrq
(
byte
irq
)
{
@Override
public
void
sendIrq
(
byte
irq
)
{
if
(
irq
>=
16
)
{
return
;
}
if
(
irq
>=
16
)
{
return
;
}
if
(
devices
[
irq
]
!=
null
)
{
tpe
.
execute
(
new
HardwareExec
(
devices
[
irq
]));
}
StackTraceElement
ste
=
Thread
.
currentThread
().
getStackTrace
()[
1
];
String
className
=
ste
.
getClassName
();
int
sendIrq
=
16
;
int
a
;
for
(
a
=
0
;
a
<
16
;
a
++)
{
if
(
devices
[
a
].
getClass
().
getCanonicalName
().
equals
(
className
))
{
sendIrq
=
a
;
break
;
}
}
if
(
devices
[
irq
]
!=
null
)
{
tpe
.
execute
(
new
HardwareRecvIrq
(
devices
[
irq
],
(
byte
)
sendIrq
));
}
}
}
@Override
public
short
length
()
{
return
(
short
)
memory
.
length
;
};
@Override
public
short
length
()
{
return
(
short
)
memory
.
length
;
};
...
@@ -233,9 +255,6 @@ public class KBoard extends BaseDevice implements IMemory {
...
@@ -233,9 +255,6 @@ public class KBoard extends BaseDevice implements IMemory {
}
}
}
}
@Override
public
void
exec
()
{
}
public
void
dumpEverything
()
{
public
void
dumpEverything
()
{
dumpMemory
(
"system"
,
memory
);
dumpMemory
(
"system"
,
memory
);
int
a
;
int
a
;
...
@@ -256,7 +275,7 @@ public class KBoard extends BaseDevice implements IMemory {
...
@@ -256,7 +275,7 @@ public class KBoard extends BaseDevice implements IMemory {
dumpMemory
(
filename
,
temp
);
dumpMemory
(
filename
,
temp
);
}
}
public
void
dumpMemory
(
String
filename
,
byte
[]
mem
)
{
public
void
dumpMemory
(
String
filename
,
byte
[]
mem
)
{
File
f
=
new
File
(
filename
.
concat
(
".mem"
));
File
f
=
new
File
(
filename
.
concat
(
".mem
.txt
"
));
try
{
System
.
out
.
println
(
String
.
format
(
"Writing %s"
,
f
.
getCanonicalPath
()));
}
catch
(
IOException
x
)
{}
try
{
System
.
out
.
println
(
String
.
format
(
"Writing %s"
,
f
.
getCanonicalPath
()));
}
catch
(
IOException
x
)
{}
try
(
FileWriter
fw
=
new
FileWriter
(
f
))
{
try
(
FileWriter
fw
=
new
FileWriter
(
f
))
{
int
max
=
mem
.
length
;
int
max
=
mem
.
length
;
...
...
src/main/java/me/felinewith/kcpu/Kasm.java
View file @
78af4d1
...
@@ -3,18 +3,22 @@ package me.felinewith.kcpu;
...
@@ -3,18 +3,22 @@ package me.felinewith.kcpu;
import
java.io.BufferedReader
;
import
java.io.BufferedReader
;
import
java.io.ByteArrayOutputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.File
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileOutputStream
;
import
java.io.FileOutputStream
;
import
java.io.FileReader
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.io.InputStreamReader
;
import
java.io.PrintStream
;
import
java.io.PrintStream
;
import
java.util.Arrays
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
import
me.felinewith.kcpu.hardware.kmcu.KmcuOpCodes
;
import
me.felinewith.kcpu.hardware.kmcu.KmcuOpCodes
;
import
me.felinewith.kcpu.opcodes.OpDirector
;
import
me.felinewith.kcpu.opcodes.OpDirector
;
import
me.felinewith.kcpu.util.Converter
;
import
me.felinewith.kcpu.util.Converter
;
import
me.felinewith.kcpu.util.helpers.ValueType
;
import
org.apache.commons.cli.CommandLine
;
import
org.apache.commons.cli.CommandLine
;
import
org.apache.commons.cli.CommandLineParser
;
import
org.apache.commons.cli.CommandLineParser
;
import
org.apache.commons.cli.DefaultParser
;
import
org.apache.commons.cli.DefaultParser
;
import
org.apache.commons.cli.HelpFormatter
;
import
org.apache.commons.cli.HelpFormatter
;
import
org.apache.commons.cli.Option
;
import
org.apache.commons.cli.Options
;
import
org.apache.commons.cli.Options
;
import
org.apache.commons.cli.ParseException
;
import
org.apache.commons.cli.ParseException
;
...
@@ -25,89 +29,259 @@ import org.apache.commons.cli.ParseException;
...
@@ -25,89 +29,259 @@ import org.apache.commons.cli.ParseException;
public
class
Kasm
{
public
class
Kasm
{
private
static
PrintStream
outer
;
private
static
PrintStream
outer
;
private
static
boolean
verbose
=
false
;
public
static
void
main
(
String
[]
args
)
{
public
static
void
main
(
String
[]
args
)
{
setOuter
(
System
.
out
);
setOuter
(
System
.
out
);
Options
opts
=
new
Options
();
Options
opts
=
new
Options
();
opts
.
addOption
(
"b"
,
"base"
,
true
,
"Base address for binary"
);
opts
.
addOption
(
Option
.
builder
(
"b"
).
longOpt
(
"base"
)
opts
.
addOption
(
"co"
,
"cpu-opcodes"
,
false
,
"Displays supported CPU opcodes"
);
.
desc
(
"Program's base address. Emitted code will assume it is loaded to this address."
)
opts
.
addOption
(
"mo"
,
"mcu-opcodes"
,
false
,
"Displays supported MCU opcodes"
);
.
hasArg
(
true
)
opts
.
addOption
(
"v"
,
"verbose"
,
false
,
"Verbose output."
);
.
argName
(
"addr"
)
opts
.
addOption
(
"kasm"
,
false
,
"Ignored."
);
.
numberOfArgs
(
1
)
opts
.
addOption
(
"help"
,
"Show this help"
);
.
build
()
);
opts
.
addOption
(
Option
.
builder
(
"c"
).
longOpt
(
"cpu"
)
.
desc
(
"Displays suppoted CPU opcodes"
)
.
build
()
);
opts
.
addOption
(
Option
.
builder
(
"m"
).
longOpt
(
"mcu"
)
.
desc
(
"Displays suported MCU opcodes."
)
.
build
()
);
opts
.
addOption
(
Option
.
builder
(
"v"
).
longOpt
(
"verbose"
)
.
desc
(
"Verbose output."
)
.
build
()
);
opts
.
addOption
(
Option
.
builder
().
longOpt
(
"kasm"
)
.
desc
(
"This option is ignored."
)
.
build
()
);
opts
.
addOption
(
Option
.
builder
(
"h"
).
longOpt
(
"help"
)
.
desc
(
"Shows this help."
)
.
build
()
);
opts
.
addOption
(
Option
.
builder
(
"o"
).
longOpt
(
"output"
)
.
desc
(
"Filename to use for building a single output file."
)
.
hasArg
()
.
argName
(
"file"
)
.
numberOfArgs
(
1
)
.
build
()
);
String
[]
files
=
Arrays
.
copyOf
(
args
,
args
.
length
);
KasmBuilder
kb
=
Kasm
.
builder
();
CommandLineParser
parser
=
new
DefaultParser
();
CommandLineParser
parser
=
new
DefaultParser
();
try
{
try
{
CommandLine
cli
=
parser
.
parse
(
opts
,
args
);
CommandLine
cli
=
parser
.
parse
(
opts
,
args
);
if
(
cli
.
hasOption
(
"help"
)
||
cli
.
hasOption
(
"c
o"
)
||
cli
.
hasOption
(
"mo
"
))
{
if
(
cli
.
hasOption
(
"help"
)
||
cli
.
hasOption
(
"c
"
)
||
cli
.
hasOption
(
"m
"
))
{
if
(
cli
.
hasOption
(
"help"
))
{
if
(
cli
.
hasOption
(
"help"
))
{
HelpFormatter
hf
=
new
HelpFormatter
();
HelpFormatter
hf
=
new
HelpFormatter
();
hf
.
printHelp
(
"kasm [options] [kasm ...]"
,
""
,
opts
,
"Non-KASM files may be ignored."
,
false
);
hf
.
printHelp
(
"kasm [options] [kasm ...]"
,
""
,
opts
,
"Non-KASM files may be ignored."
,
false
);
}
}
if
(
cli
.
hasOption
(
"c
o
"
))
{
if
(
cli
.
hasOption
(
"c
pu
"
))
{
logln
(
"Supported CPU Opcodes:"
);
logln
(
"Supported CPU Opcodes:"
);
for
(
OpDirector
oc
:
OpDirector
.
values
())
{
for
(
OpDirector
oc
:
OpDirector
.
values
())
{
logln
(
"\t[%10s] %s"
,
oc
.
name
(),
oc
.
getDescription
());
logln
(
"\t[%10s] %s"
,
oc
.
name
(),
oc
.
getDescription
());
}
}
logln
(
""
);
logln
(
""
);
}
}
if
(
cli
.
hasOption
(
"m
o
"
))
{
if
(
cli
.
hasOption
(
"m
cu
"
))
{
logln
(
"Supported MCU Opcodes:"
);
logln
(
"Supported MCU Opcodes:"
);
for
(
KmcuOpCodes
oc
:
KmcuOpCodes
.
values
())
{
for
(
KmcuOpCodes
oc
:
KmcuOpCodes
.
values
())
{
logln
(
"\t
%04x -> [%10s]"
,
oc
.
getOpcode
(),
oc
.
name
());
logln
(
"\t
[%10s] %s"
,
oc
.
name
(),
oc
.
getDescription
());
}
}
logln
(
""
);
logln
(
""
);
}
}
return
;
return
;
}
}
if
(
cli
.
hasOption
(
"v"
))
{
verbose
=
true
;
}
if
(
cli
.
hasOption
(
"verbose"
))
{
kb
.
setVerbose
(
true
);
}
if
(
cli
.
hasOption
(
"base"
))
{
kb
.
setBASEaddr
(
Short
.
valueOf
(
cli
.
getOptionValue
(
"base"
)));
}
if
(
cli
.
hasOption
(
"output"
))
{
kb
.
setFile
(
cli
.
getOptionValue
(
"output"
));
}
files
=
cli
.
getArgs
();
}
}
catch
(
ParseException
x
)
{
catch
(
ParseException
x
)
{
logln
(
"Parser error: %s"
,
x
.
getMessage
());
logln
(
"Parser error: %s"
,
x
.
getMessage
());
HelpFormatter
hf
=
new
HelpFormatter
();
HelpFormatter
hf
=
new
HelpFormatter
();
hf
.
printHelp
(
"kasm [options] [kasm files]"
,
"Header"
,
opts
,
"Footer\nNote: Non-KASM text files may be ignored."
,
true
);
hf
.
printHelp
(
"kasm [options] [kasm files]"
,
"Header"
,
opts
,
"Note: Non-KASM text files may be ignored."
,
true
);
return
;
return
;
}
}
for
(
String
a
:
args
)
{
Kasm
kasm
=
kb
.
build
();
for
(
String
a
:
files
)
{
if
(
a
.
endsWith
(
".kasm"
)
)
{
if
(
a
.
endsWith
(
".kasm"
)
)
{
try
{
assemble
(
a
);
}
try
{
kasm
.
assemble
(
a
);
kasm
.
reset
();
}
catch
(
IOException
x
)
{}
catch
(
IOException
x
)
{}
}
}
}
}
kasm
.
close
();
}
}
static
void
assemble
(
String
filename
)
throws
IOException
{
assemble
(
new
File
(
filename
));}
/**
static
void
assemble
(
File
file
)
throws
IOException
{
* @return the outer
File
out
=
new
File
(
file
.
getCanonicalPath
().
concat
(
".kc"
));
*/
public
static
PrintStream
getOuter
()
{
return
outer
;
}
logln
(
"\nInput : %s\nOutput: %s"
,
file
.
getCanonicalPath
(),
out
.
getCanonicalPath
());
/**
FileInputStream
fis
=
new
FileInputStream
(
file
);
* @param aOuter the outer to set
FileOutputStream
fos
=
new
FileOutputStream
(
out
);
*/
public
static
void
setOuter
(
PrintStream
aOuter
)
{
outer
=
aOuter
;
}
InputStreamReader
isr
=
new
InputStreamReader
(
fis
);
private
static
void
log
(
String
format
,
Object
...
vals
)
{
BufferedReader
br
=
new
BufferedReader
(
isr
);
if
(
outer
==
null
)
{
return
;
}
outer
.
print
(
String
.
format
(
format
,
vals
));
}
private
static
void
logln
(
String
format
,
Object
...
vals
)
{
if
(
outer
==
null
)
{
return
;
}
outer
.
println
(
String
.
format
(
format
,
vals
));
}
public
static
KasmBuilder
builder
()
{
return
new
Kasm
.
KasmBuilder
();
}
private
short
BASEaddr
;
private
short
mark
;
private
boolean
verbose
;
private
File
outFile
=
null
;
private
FileOutputStream
fileOutputStream
=
null
;
private
ByteArrayOutputStream
baos
;
private
short
pc
;
private
Kasm
()
{
}
private
Kasm
(
KasmBuilder
builder
)
{
BASEaddr
=
builder
.
BASEaddr
;
if
(
builder
.
file
!=
null
)
{
outFile
=
builder
.
file
;
try
{
fileOutputStream
=
new
FileOutputStream
(
outFile
);
}
catch
(
IOException
x
)
{}
}
verbose
=
builder
.
verbose
;
baos
=
new
ByteArrayOutputStream
();
}
private
String
stripType
(
String
input
)
{
if
(
input
.
contains
(
"."
))
{
return
input
.
substring
(
input
.
indexOf
(
'.'
)
+
1
);
}
switch
(
input
.
charAt
(
0
))
{
case
'R'
:
case
'r'
:
case
'%'
:
case
'$'
:
return
input
.
substring
(
1
);
}
return
input
;
}
private
short
asmType
(
String
input
)
{
String
test
=
input
.
toLowerCase
();
if
(
test
.
startsWith
(
"d."
))
{
return
ValueType
.
D
.
getValue
();
}
else
if
(
test
.
startsWith
(
"r"
)
||
test
.
startsWith
(
"r."
))
{
return
ValueType
.
R
.
getValue
();
}
else
if
(
test
.
startsWith
(
"%"
)
||
test
.
startsWith
(
"ad."
))
{
return
ValueType
.
AD
.
getValue
();
}
else
if
(
test
.
startsWith
(
"$"
)
||
test
.
startsWith
(
"ar."
))
{
return
ValueType
.
AR
.
getValue
();
}
return
ValueType
.
D
.
getValue
();
}
private
short
numberize
(
String
input
)
{
String
temp
=
stripType
(
input
).
toUpperCase
();
String
[]
pt
;
int
tmp
;
// remove underscores, which are useful in reading numbers in code
if
(
temp
.
contains
(
"_"
))
{
temp
=
temp
.
replaceAll
(
"_"
,
""
);
}
// replace assembler keywords with numbers
if
(
temp
.
contains
(
"BASE"
))
{
temp
=
temp
.
replaceAll
(
"BASE"
,
String
.
format
(
"%d"
,
BASEaddr
));
}
if
(
temp
.
contains
(
"MARK"
))
{
temp
=
temp
.
replaceAll
(
"MARK"
,
String
.
format
(
"%d"
,
mark
));
}
Pattern
p
=
Pattern
.
compile
(
"([0-9a-f]+),([0-9]+)"
,
Pattern
.
CASE_INSENSITIVE
);
Matcher
m
=
p
.
matcher
(
temp
);
// convert radix'd numbers
short
radix
;
while
(
m
.
find
())
{
radix
=
Short
.
valueOf
(
m
.
group
(
2
),
10
);
tmp
=
Integer
.
valueOf
(
m
.
group
(
1
),
radix
);
temp
=
temp
.
replace
(
m
.
group
(),
String
.
format
(
"%d"
,
(
short
)(
0xffff
&
tmp
)));
m
.
reset
(
temp
);
}
// perform any required math
p
=
Pattern
.
compile
(
"([0-9a-f]+)([-+*\\/])([0-9a-f]+)"
,
Pattern
.
CASE_INSENSITIVE
);
m
=
p
.
matcher
(
temp
);
while
(
m
.
find
())
{
switch
(
m
.
group
(
2
))
{
case
"+"
:
tmp
=
Integer
.
valueOf
(
m
.
group
(
1
))
+
Integer
.
valueOf
(
m
.
group
(
3
));
temp
=
temp
.
replace
(
m
.
group
(),
String
.
format
(
"%d"
,
(
short
)(
0xffff
&
tmp
)));
break
;
case
"-"
:
tmp
=
Integer
.
valueOf
(
m
.
group
(
1
))
-
Integer
.
valueOf
(
m
.
group
(
3
));
temp
=
temp
.
replace
(
m
.
group
(),
String
.
format
(
"%d"
,
(
short
)(
0xffff
&
tmp
)));
break
;
case
"*"
:
tmp
=
Integer
.
valueOf
(
m
.
group
(
1
))
*
Integer
.
valueOf
(
m
.
group
(
3
));
temp
=
temp
.
replace
(
m
.
group
(),
String
.
format
(
"%d"
,
(
short
)(
0xffff
&
tmp
)));
break
;
case
"/"
:
tmp
=
Integer
.
valueOf
(
m
.
group
(
1
))
/
Integer
.
valueOf
(
m
.
group
(
3
));
temp
=
temp
.
replace
(
m
.
group
(),
String
.
format
(
"%d"
,
(
short
)(
0xffff
&
tmp
)));
break
;
}
m
.
reset
(
temp
);
}
return
(
short
)(
0xffff
&
Integer
.
valueOf
(
temp
));
}
void
assemble
(
String
filename
)
throws
IOException
{
assemble
(
new
File
(
filename
));}
void
assemble
(
File
file
)
throws
IOException
{
String
fn
=
file
.
getCanonicalPath
();
fn
=
fn
.
substring
(
0
,
fn
.
lastIndexOf
(
'.'
));
File
out
=
new
File
(
String
.
format
(
"%s.kc"
,
fn
));
logln
(
"\nInput : %s\nOutput: %s"
,
file
.
getCanonicalPath
(),
(
outFile
==
null
)?
out
.
getCanonicalPath
():
outFile
.
getCanonicalPath
());
readFromFile
(
file
);
sendToFile
(
out
);
}
public
void
readFromFile
(
String
filename
)
throws
IOException
{
readFromFile
(
new
File
(
filename
));}
public
void
readFromFile
(
File
file
)
throws
IOException
{
FileReader
fr
=
new
FileReader
(
file
);
BufferedReader
br
=
new
BufferedReader
(
fr
);
String
line
;
String
line
;
byte
[]
temp
;
int
a
;
while
((
line
=
br
.
readLine
())
!=
null
)
{
while
((
line
=
br
.
readLine
())
!=
null
)
{
temp
=
compile
(
line
);
compile
(
line
);
fos
.
write
(
temp
);
}
}
fos
.
flush
();
}
fos
.
close
();
public
void
sendToFile
(
String
filename
)
throws
IOException
{
sendToFile
(
new
File
(
filename
));
}
public
void
sendToFile
(
File
file
)
throws
IOException
{
if
(
outFile
==
null
)
{
baos
.
writeTo
(
new
FileOutputStream
(
file
));
}
else
{
baos
.
writeTo
(
fileOutputStream
);
}
baos
.
reset
();
}
br
.
close
();
public
void
compile
(
String
[]
kasm
)
{
isr
.
close
();
for
(
String
s
:
kasm
)
{
compile
(
s
);
}
fis
.
close
();
}
public
void
compile
(
String
kasm
)
{
byte
[]
temp
=
compileSegment
(
kasm
);
baos
.
write
(
temp
,
0
,
temp
.
length
);
}
}
static
public
byte
[]
compile
(
String
kasm
)
{
public
byte
[]
compileSegment
(
String
[]
kasm
)
{
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream
();
ByteArrayOutputStream
output
=
new
ByteArrayOutputStream
();
byte
[]
temp
;
for
(
String
s
:
kasm
)
{
temp
=
compileSegment
(
s
);
output
.
write
(
temp
,
0
,
temp
.
length
);
}
return
output
.
toByteArray
();
}
public
byte
[]
compileSegment
(
String
kasm
)
{
ByteArrayOutputStream
output
=
new
ByteArrayOutputStream
();
if
(
kasm
.
startsWith
(
"#"
)
||
kasm
.
startsWith
(
"//"
)
||
kasm
.
length
()
==
0
)
{}
if
(
kasm
.
startsWith
(
"#"
)
||
kasm
.
startsWith
(
"//"
)
||
kasm
.
length
()
==
0
)
{}
else
{
else
{
if
(
kasm
.
contains
(
"#"
))
{
kasm
=
kasm
.
substring
(
0
,
kasm
.
indexOf
(
"#"
)
-
1
);
}
if
(
kasm
.
contains
(
"//"
))
{
kasm
=
kasm
.
substring
(
0
,
kasm
.
indexOf
(
"//"
)
-
1
);
}
String
[]
parts
;
String
[]
parts
;
OpDirector
opcode
;
OpDirector
opcode
;
short
ref
=
0
;
short
ref
=
0
;
...
@@ -116,18 +290,27 @@ public class Kasm {
...
@@ -116,18 +290,27 @@ public class Kasm {
else
{
parts
=
new
String
[]{
kasm
};
}
else
{
parts
=
new
String
[]{
kasm
};
}
parts
[
0
]
=
parts
[
0
].
toUpperCase
();
parts
[
0
]
=
parts
[
0
].
toUpperCase
();
if
(
parts
[
0
].
equals
(
"FILL"
))
{
if
(
parts
[
0
].
equals
(
"MARK"
))
{
mark
=
pc
;
return
new
byte
[
0
];
}
else
if
(
parts
[
0
].
equals
(
"FILL"
))
{
int
a
;
int
a
;
int
max
=
numberize
(
parts
[
1
]);
int
max
=
numberize
(
parts
[
1
]);
byte
fill
=
0
;
byte
fill
=
0
;
if
(
parts
.
length
>=
3
)
{
fill
=
(
byte
)
numberize
(
parts
[
2
]);
}
if
(
parts
.
length
>=
3
)
{
fill
=
(
byte
)(
0xff
&
numberize
(
parts
[
2
]));
}
for
(
a
=
0
;
a
<
max
;
a
++)
{
baos
.
write
(
fill
);
}
byte
[]
bytes
=
compileSegment
(
String
.
format
(
"jmpu %d"
,
max
));
return
baos
.
toByteArray
();
output
.
write
(
bytes
,
0
,
bytes
.
length
);
for
(
a
=
0
;
a
<
max
;
a
++)
{
output
.
write
(
fill
);
}
pc
+=
output
.
size
();
return
output
.
toByteArray
();
}
}
else
{
else
{
opcode
=
OpDirector
.
valueOf
(
parts
[
0
]);
opcode
=
OpDirector
.
valueOf
(
parts
[
0
]);
if
(
verbose
)
{
log
(
"[%10s] "
,
opcode
.
name
());
}
if
(
verbose
)
{
log
(
"[%10s] "
,
opcode
.
name
());
}
writeShort
(
baos
,
opcode
.
getOpcode
());
writeShort
(
output
,
opcode
.
getOpcode
());
short
plen
=
(
short
)
parts
.
length
;
if
(
plen
>=
5
)
{
plen
=
5
;
}
plen
=
(
short
)(
2
+
(
plen
*
2
));
pc
+=
plen
;
if
(
verbose
)
{
log
(
" : "
);
}
if
(
verbose
)
{
log
(
" : "
);
}
if
(
parts
.
length
>=
2
)
{
ref
+=
asmType
(
parts
[
1
]);
}
if
(
parts
.
length
>=
2
)
{
ref
+=
asmType
(
parts
[
1
]);
}
...
@@ -140,90 +323,53 @@ public class Kasm {
...
@@ -140,90 +323,53 @@ public class Kasm {
else
if
(
parts
.
length
>=
3
)
{
ref
+=
0x0200
;
}
else
if
(
parts
.
length
>=
3
)
{
ref
+=
0x0200
;
}
else
if
(
parts
.
length
>=
2
)
{
ref
+=
0x0100
;
}
else
if
(
parts
.
length
>=
2
)
{
ref
+=
0x0100
;
}
writeShort
(
baos
,
ref
);
writeShort
(
output
,
ref
);
if
(
verbose
)
{
log
(
" -> "
);
}
if
(
verbose
)
{
log
(
" -> "
);
}
if
(
parts
.
length
>=
2
)
{
writeShort
(
baos
,
numberize
(
parts
[
1
]));
}
if
(
parts
.
length
>=
2
)
{
writeShort
(
output
,
numberize
(
parts
[
1
]));
}
if
(
parts
.
length
>=
3
)
{
writeShort
(
baos
,
numberize
(
parts
[
2
]));
}
if
(
parts
.
length
>=
3
)
{
writeShort
(
output
,
numberize
(
parts
[
2
]));
}
if
(
parts
.
length
>=
4
)
{
writeShort
(
baos
,
numberize
(
parts
[
3
]));
}
if
(
parts
.
length
>=
4
)
{
writeShort
(
output
,
numberize
(
parts
[
3
]));
}
if
(
parts
.
length
>=
5
)
{
writeShort
(
baos
,
numberize
(
parts
[
4
]));
}
if
(
parts
.
length
>=
5
)
{
writeShort
(
output
,
numberize
(
parts
[
4
]));
}
if
(
verbose
)
{
logln
(
""
);
}
if
(
verbose
)
{
logln
(
""
);
}
}
}
}
}
return
baos
.
toByteArray
();
return
output
.
toByteArray
();
}
}
static
void
writeShort
(
ByteArrayOutputStream
baos
,
short
value
)
{
void
writeShort
(
ByteArrayOutputStream
output
,
short
value
)
{
byte
[]
temp
=
Converter
.
short2bytes
(
value
);
byte
[]
temp
=
Converter
.
short2bytes
(
value
);
if
(
verbose
)
{
log
(
"%02x%02x "
,
temp
[
0
],
temp
[
1
]);
}
if
(
verbose
)
{
log
(
"%02x%02x "
,
temp
[
0
],
temp
[
1
]);
}
baos
.
write
(
temp
,
0
,
temp
.
length
);
output
.
write
(
temp
,
0
,
temp
.
length
);
}
static
void
writeShort
(
FileOutputStream
fos
,
short
value
)
throws
IOException
{
byte
[]
v
=
Converter
.
short2bytes
(
value
);
if
(
verbose
)
{
log
(
"[%02x%02x]"
,
v
[
0
],
v
[
1
]);
}
fos
.
write
(
v
);
}
}
static
String
stripType
(
String
input
)
{
public
void
reset
()
{
baos
.
reset
();
}
if
(
asmType
(
input
)
==
0
)
{
return
input
;
}
public
void
close
()
{
return
input
.
substring
(
1
);
if
(
fileOutputStream
!=
null
)
{
}
try
{
fileOutputStream
.
close
();
}
catch
(
IOException
x
)
{}
static
short
asmType
(
String
input
)
{
return
asmType
(
input
.
charAt
(
0
));
}
static
short
asmType
(
char
input
)
{
switch
(
input
)
{
case
'r'
:
return
0x01
;
case
'%'
:
return
0x02
;
case
'$'
:
return
0x03
;
default
:
return
0x00
;
}
}
static
short
numberize
(
String
input
)
{
String
temp
=
stripType
(
input
);
String
[]
pt
;
if
(
temp
.
contains
(
"_"
))
{
temp
=
temp
.
replaceAll
(
"_"
,
""
);
}
if
(
temp
.
contains
(
","
))
{
pt
=
temp
.
split
(
"[,]"
);
short
radix
=
Short
.
valueOf
(
pt
[
1
],
10
);
return
(
short
)(
0xffff
&
Integer
.
valueOf
(
pt
[
0
],
radix
));
}
}
else
{
return
(
short
)(
0xffff
&
Integer
.
valueOf
(
temp
));
}
}
/**
* @return the outer
*/
public
static
PrintStream
getOuter
()
{
return
outer
;
}
/**
* @param aOuter the outer to set
*/
public
static
void
setOuter
(
PrintStream
aOuter
)
{
outer
=
aOuter
;
}
private
static
void
log
(
String
format
,
Object
...
vals
)
{
if
(
outer
==
null
)
{
return
;
}
outer
.
print
(
String
.
format
(
format
,
vals
));
}
private
static
void
logln
(
String
format
,
Object
...
vals
)
{
if
(
outer
==
null
)
{
return
;
}
outer
.
println
(
String
.
format
(
format
,
vals
));
}
public
static
KasmBuilder
builder
()
{
return
new
Kasm
.
KasmBuilder
();
}
short
BASEaddr
;
private
Kasm
()
{
}
private
Kasm
(
KasmBuilder
builder
)
{
BASEaddr
=
builder
.
BASEaddr
;
}
}
public
static
class
KasmBuilder
{
public
static
class
KasmBuilder
{
short
BASEaddr
;
short
BASEaddr
=
0
;
boolean
verbose
=
false
;
File
file
=
null
;
public
KasmBuilder
()
{
}
public
KasmBuilder
()
{
}
public
Kasm
build
()
{
return
new
Kasm
(
this
);
}
public
Kasm
build
()
{
return
new
Kasm
(
this
);
}
public
KasmBuilder
setBASEaddr
(
short
BASEaddr
)
{
this
.
BASEaddr
=
BASEaddr
;
return
this
;
}
public
KasmBuilder
setBASEaddr
(
short
BASEaddr
)
{
this
.
BASEaddr
=
BASEaddr
;
return
this
;
}
public
KasmBuilder
setFile
(
String
file
)
{
String
temp
=
file
;
int
t
=
file
.
lastIndexOf
(
'.'
);
if
(
t
==
-
1
)
{
temp
=
String
.
format
(
"%s.kc"
,
file
);
}
else
if
(!
file
.
substring
(
t
+
1
).
equals
(
"kc"
))
{
temp
=
String
.
format
(
"%s.kc"
,
file
.
substring
(
0
,
t
));
}
return
setFile
(
new
File
(
temp
));
}
public
KasmBuilder
setFile
(
File
file
)
{
this
.
file
=
file
;
return
this
;
}
public
KasmBuilder
setVerbose
(
boolean
verbose
)
{
this
.
verbose
=
verbose
;
return
this
;
}
}
}
}
}
src/main/java/me/felinewith/kcpu/Kcpu.java
View file @
78af4d1
package
me
.
felinewith
.
kcpu
;
package
me
.
felinewith
.
kcpu
;
import
java.io.PrintStream
;
import
java.io.PrintStream
;
import
java.util.Arrays
;
import
me.felinewith.kcpu.interfaces.IMemory
;
import
me.felinewith.kcpu.interfaces.IMemory
;
import
me.felinewith.kcpu.opcodes.OpDirector
;
import
me.felinewith.kcpu.opcodes.OpDirector
;
import
me.felinewith.kcpu.util.BaseDevice
;
import
me.felinewith.kcpu.util.BaseDevice
;
import
me.felinewith.kcpu.util.CPUStoppedException
;
import
me.felinewith.kcpu.util.Converter
;
import
me.felinewith.kcpu.util.helpers.MemHelper
;
import
me.felinewith.kcpu.util.helpers.MemHelper
;
import
me.felinewith.kcpu.util.helpers.ValueHelper
;
import
me.felinewith.kcpu.util.helpers.ValueHelper
;
import
me.felinewith.kcpu.util.helpers.ValueType
;
import
me.felinewith.kcpu.util.helpers.ValueType
;
...
@@ -42,9 +45,20 @@ public class Kcpu extends BaseDevice {
...
@@ -42,9 +45,20 @@ public class Kcpu extends BaseDevice {
short
[]
registers
;
short
[]
registers
;
private
KBoard
kboard
;
private
KBoard
kboard
;
Thread
initThread
;
public
Kcpu
(
KBoard
system
)
{
public
Kcpu
(
KBoard
system
)
{
memory
=
new
byte
[
0x0800
];
/**
* memory ranges:
* 0x0000 - 0x00ff : data stack
* 0x0100 - 0x017f : pc stack (return stack)
* 0x0180 - 0x019f : interrupt vectors
* 0x0120 : data stack pointer
* 0x0122 : pc stack pointer
* 0x0124 ~ unused
* 0x01ff : interrupt (boolean value)
*/
memory
=
new
byte
[
0x0200
];
name
=
"Kcpu"
;
name
=
"Kcpu"
;
settings
=
new
short
[
6
];
settings
=
new
short
[
6
];
kboard
=
system
;
kboard
=
system
;
...
@@ -54,30 +68,45 @@ public class Kcpu extends BaseDevice {
...
@@ -54,30 +68,45 @@ public class Kcpu extends BaseDevice {
}
}
@Override
public
void
init
(
IMemory
system
)
{
@Override
public
void
init
(
IMemory
system
)
{
initThread
=
Thread
.
currentThread
();
setOuter
(
System
.
err
);
setOuter
(
System
.
err
);
}
}
@Override
public
void
exec
()
{
workCycle
();
}
// need to prevent other devices from writing to CPU internals
@Override
public
void
write
(
short
offset
,
byte
data
)
{
}
@Override
public
byte
read
(
short
addr
)
{
@Override
public
void
recvIrq
(
byte
irq
)
{
if
(
(
0xffff
&
addr
)
>
length
()
)
{
return
(
byte
)
0xff
;
}
synchronized
(
initThread
)
{
return
memory
[
0xffff
&
addr
];
short
[]
regs
=
Arrays
.
copyOf
(
registers
,
registers
.
length
);
}
short
counter
=
pc
;
if
(
Thread
.
currentThread
().
getId
()
!=
initThread
.
getId
())
{
initThread
.
interrupt
();
regs
=
Arrays
.
copyOf
(
registers
,
registers
.
length
);
counter
=
pc
;
}
@Override
public
void
write
(
short
offset
,
byte
data
)
{
}
short
start
=
(
short
)((
irq
*
2
)
+
0x0180
);
@Override
public
void
copy
(
short
addrSrc
,
short
addrDest
,
IMemory
dest
)
{
}
pc
=
Converter
.
bytes2short
(
new
byte
[]{
memory
[
start
],
memory
[
start
+
1
]});
try
{
while
(
true
)
{
workCycle
();
Thread
.
yield
();
}
}
catch
(
CPUStoppedException
x
)
{}
@Override
public
void
memIrq
(
short
addr
)
{
if
(
Thread
.
currentThread
().
getId
()
!=
initThread
.
getId
())
{
if
(
0
<=
addr
&&
addr
<=
memory
.
length
)
{
exec
();
}
registers
=
Arrays
.
copyOf
(
regs
,
regs
.
length
);
pc
=
counter
;
initThread
.
notify
();
}
}
}
}
public
int
workCycle
()
{
public
void
workCycle
()
throws
CPUStoppedException
{
if
(
pc
>=
0xfff0
)
{
pc
=
0
;
}
if
(
pc
>=
0xfff0
)
{
pc
=
0
;
}
short
inst
=
MemHelper
.
readShort
(
pc
,
kboard
);
short
inst
=
MemHelper
.
readShort
(
pc
,
kboard
);
short
ref
=
MemHelper
.
readShort
(
pc
+
2
,
kboard
);
short
ref
=
MemHelper
.
readShort
(
pc
+
2
,
kboard
);
short
[]
values
=
new
short
[
4
]
;
short
[]
values
=
new
short
[
]{(
short
)
0
,
(
short
)
1
,
(
short
)
2
,
(
short
)
3
}
;
if
((
0xffff
&
inst
)
==
0xff
ff
){
if
((
0xffff
&
inst
)
==
0xff
1b
){
log
ln
(
"Break!
"
);
log
(
"
"
);
}
}
switch
(
0x0700
&
ref
)
{
switch
(
0x0700
&
ref
)
{
case
0x0700
:
case
0x0600
:
case
0x0500
:
case
0x0700
:
case
0x0600
:
case
0x0500
:
...
@@ -96,8 +125,20 @@ public class Kcpu extends BaseDevice {
...
@@ -96,8 +125,20 @@ public class Kcpu extends BaseDevice {
}
}
log
(
"%04x : [%10s] %04x ->"
,
pc
,
((
od
==
null
)?
"nop"
:
od
.
name
()),
ref
);
log
(
"%04x : [%10s] %04x ->"
,
pc
,
((
od
==
null
)?
"nop"
:
od
.
name
()),
ref
);
log
(
" %04x %04x %04x %04x "
,
registers
[
0
],
registers
[
1
],
registers
[
2
],
registers
[
3
]);
log
(
" %04x %04x %04x %04x\t\t"
,
registers
[
0
],
registers
[
1
],
registers
[
2
],
registers
[
3
]);
// bring up the program counter
if
(
od
==
null
)
{
pc
+=
12
;
return
;
}
// inc if nop
pc
+=
4
;
pc
+=
(((
0x0700
&
ref
)
>>
8
)
*
2
);
// this works because the value starts counting at 1
switch
(
0x0700
&
ref
)
{
case
0x0000
:
ref
+=
ValueType
.
R
.
getValue
();
case
0x0100
:
ref
+=
(
ValueType
.
R
.
getValue
()
<<
2
);
case
0x0200
:
ref
+=
(
ValueType
.
R
.
getValue
()
<<
4
);
case
0x0300
:
ref
+=
(
ValueType
.
R
.
getValue
()
<<
6
);
}
if
((
0x0700
&
ref
)
>=
0x0100
)
{
log
(
" %2s.%04x"
,
ValueType
.
valueOf
(
ref
,
0
),
values
[
0
]);
}
if
((
0x0700
&
ref
)
>=
0x0100
)
{
log
(
" %2s.%04x"
,
ValueType
.
valueOf
(
ref
,
0
),
values
[
0
]);
}
if
((
0x0700
&
ref
)
>=
0x0200
)
{
log
(
" %2s.%04x"
,
ValueType
.
valueOf
(
ref
,
1
),
values
[
1
]);
}
if
((
0x0700
&
ref
)
>=
0x0200
)
{
log
(
" %2s.%04x"
,
ValueType
.
valueOf
(
ref
,
1
),
values
[
1
]);
}
...
@@ -105,72 +146,65 @@ public class Kcpu extends BaseDevice {
...
@@ -105,72 +146,65 @@ public class Kcpu extends BaseDevice {
if
((
0x0700
&
ref
)
>=
0x0400
)
{
log
(
" %2s.%04x"
,
ValueType
.
valueOf
(
ref
,
3
),
values
[
3
]);
}
if
((
0x0700
&
ref
)
>=
0x0400
)
{
log
(
" %2s.%04x"
,
ValueType
.
valueOf
(
ref
,
3
),
values
[
3
]);
}
logln
(
""
);
logln
(
""
);
if
(
od
==
null
)
{
pc
+=
12
;
return
0
;
}
// inc if nop
pc
+=
4
;
pc
+=
(((
0x0700
&
ref
)
>>
8
)
*
2
);
if
(
od
.
hasHandler
()
)
{
if
(
od
.
hasHandler
()
)
{
registers
=
od
.
call
(
pc
,
ref
,
registers
,
values
,
kboard
);
registers
=
od
.
call
(
pc
,
ref
,
registers
,
values
,
kboard
);
return
0
;
return
;
}
}
short
data
=
ValueHelper
.
readShort
(
0
,
ref
,
registers
,
values
,
kboard
);
short
data
=
ValueHelper
.
readShort
(
0
,
ref
,
registers
,
values
,
kboard
);
switch
(
od
)
{
switch
(
od
)
{
// device management
// device management
case
DEVA:
registers
[
0
]
=
kboard
.
checkDevice
(
data
);
return
0
;
case
DEVA:
registers
[
0
]
=
kboard
.
checkDevice
(
data
);
return
;
case
DEVD:
kboard
.
detachDevice
(
data
);
return
0
;
case
DEVD:
kboard
.
detachDevice
(
data
);
return
;
case
DEVM:
case
DEVM:
kboard
.
setDeviceRange
(
data
,
ValueHelper
.
readShort
(
1
,
ref
,
registers
,
values
,
kboard
));
kboard
.
setDeviceRange
(
data
,
ValueHelper
.
readShort
(
1
,
ref
,
registers
,
values
,
kboard
));
return
0
;
return
;
case
DEVP:
case
DEVP:
KMemoryRange
kmr
=
kboard
.
getDeviceRange
(
data
);
KMemoryRange
kmr
=
kboard
.
getDeviceRange
(
data
);
registers
[
0
]
=
kmr
.
getOffset
();
registers
[
0
]
=
kmr
.
getOffset
();
registers
[
1
]
=
kmr
.
getLength
();
registers
[
1
]
=
kmr
.
getLength
();
return
0
;
return
;
// interrupts
// interrupts
case
IRQD:
kboard
.
sendIrq
((
byte
)(
0x000f
&
data
));
return
0
;
case
IRQD:
kboard
.
sendIrq
((
byte
)(
0x000f
&
data
));
return
;
case
IRQM:
kboard
.
memIrq
(
data
);
return
0
;
case
IRQM:
kboard
.
memIrq
(
data
,
(
byte
)
0
);
return
;
// jumps
// jumps
case
JMP:
pc
=
(
short
)(
pc
+
(
0xffff
&
data
));
return
0
;
case
JMP:
case
JMPU:
pc
=
(
short
)(
pc
+
(
0xffff
&
data
));
return
;
case
JMPA:
pc
=
data
;
return
0
;
case
JMPA:
pc
=
data
;
return
;
case
JMPD:
pc
=
(
short
)(
pc
-
(
0xffff
&
data
));
return
0
;
case
JMPD:
pc
=
(
short
)(
pc
-
(
0xffff
&
data
));
return
;
case
GPC:
case
GPC:
registers
=
ValueHelper
.
writeShort
(
0
,
ref
,
registers
,
values
,
kboard
,
pc
)
;
registers
[
0
]
=
pc
;
return
0
;
return
;
case
ZPWR:
return
0xff
;
case
ZPWR:
throw
new
CPUStoppedException
(
"zpwr"
)
;
}
}
short
data2
=
ValueHelper
.
readShort
(
1
,
ref
,
registers
,
values
,
kboard
);
short
data2
=
ValueHelper
.
readShort
(
1
,
ref
,
registers
,
values
,
kboard
);
short
data3
=
ValueHelper
.
readShort
(
2
,
ref
,
registers
,
values
,
kboard
);
short
data3
=
ValueHelper
.
readShort
(
2
,
ref
,
registers
,
values
,
kboard
);
switch
(
od
)
{
switch
(
od
)
{
// conditionals
// conditionals
case
JE:
if
(
data
==
data2
)
{
pc
+=
data3
;
}
return
0
;
case
JE:
if
(
data
==
data2
)
{
pc
+=
data3
;
}
return
;
case
JAE:
if
(
data
==
data2
)
{
pc
=
data3
;
}
return
0
;
case
JAE:
if
(
data
==
data2
)
{
pc
=
data3
;
}
return
;
case
JDE:
if
(
data
==
data2
)
{
pc
-=
data3
;
}
return
0
;
case
JDE:
if
(
data
==
data2
)
{
pc
-=
data3
;
}
return
;
case
JG:
if
(
data
>
data2
)
{
pc
+=
data3
;
}
return
0
;
case
JG:
if
(
data
>
data2
)
{
pc
+=
data3
;
}
return
;
case
JAG:
if
(
data
>
data2
)
{
pc
=
data3
;
}
return
0
;
case
JAG:
if
(
data
>
data2
)
{
pc
=
data3
;
}
return
;
case
JDG:
if
(
data
>
data2
)
{
pc
-=
data3
;
}
return
0
;
case
JDG:
if
(
data
>
data2
)
{
pc
-=
data3
;
}
return
;
case
JL:
if
(
data
<
data2
)
{
pc
+=
data3
;
}
return
0
;
case
JL:
if
(
data
<
data2
)
{
pc
+=
data3
;
}
return
;
case
JAL:
if
(
data
<
data2
)
{
pc
=
data3
;
}
return
0
;
case
JAL:
if
(
data
<
data2
)
{
pc
=
data3
;
}
return
;
case
JDL:
if
(
data
<
data2
)
{
pc
-=
data3
;
}
return
0
;
case
JDL:
if
(
data
<
data2
)
{
pc
-=
data3
;
}
return
;
case
JGE:
if
(
data
>=
data2
)
{
pc
+=
data3
;
}
return
0
;
case
JGE:
if
(
data
>=
data2
)
{
pc
+=
data3
;
}
return
;
case
JAGE:
if
(
data
>=
data2
)
{
pc
=
data3
;
}
return
0
;
case
JAGE:
if
(
data
>=
data2
)
{
pc
=
data3
;
}
return
;
case
JDGE:
if
(
data
>=
data2
)
{
pc
-=
data3
;
}
return
0
;
case
JDGE:
if
(
data
>=
data2
)
{
pc
-=
data3
;
}
return
;
case
JLE:
if
(
data
<=
data2
)
{
pc
+=
data3
;
}
return
0
;
case
JLE:
if
(
data
<=
data2
)
{
pc
+=
data3
;
}
return
;
case
JALE:
if
(
data
<=
data2
)
{
pc
=
data3
;
}
return
0
;
case
JALE:
if
(
data
<=
data2
)
{
pc
=
data3
;
}
return
;
case
JDLE:
if
(
data
<=
data2
)
{
pc
-=
data3
;
}
return
0
;
case
JDLE:
if
(
data
<=
data2
)
{
pc
-=
data3
;
}
return
;
case
VCMP:
case
VCMP:
registers
[
0
]
=
0
;
registers
[
0
]
=
0
;
if
(
data
!=
data2
)
{
registers
[
0
]
+=
0x0001
;
}
if
(
data
!=
data2
)
{
registers
[
0
]
+=
0x0001
;
}
if
(
data
>=
data2
)
{
registers
[
0
]
+=
0x0002
;
}
if
(
data
>=
data2
)
{
registers
[
0
]
+=
0x0002
;
}
if
(
data
==
data2
)
{
registers
[
0
]
+=
0x0004
;
}
if
(
data
==
data2
)
{
registers
[
0
]
+=
0x0004
;
}
if
(
data
<=
data2
)
{
registers
[
0
]
+=
0x0008
;
}
if
(
data
<=
data2
)
{
registers
[
0
]
+=
0x0008
;
}
return
0
;
}
}
return
0
;
}
}
}
}
src/main/java/me/felinewith/kcpu/Kemulator.java
View file @
78af4d1
...
@@ -30,7 +30,7 @@ public class Kemulator {
...
@@ -30,7 +30,7 @@ public class Kemulator {
ArrayList
<
Option
>
option
=
new
ArrayList
<>();
ArrayList
<
Option
>
option
=
new
ArrayList
<>();
option
.
add
(
Option
.
builder
(
"b"
)
option
.
add
(
Option
.
builder
(
"b"
)
.
longOpt
(
"bootrom"
)
.
longOpt
(
"bootrom"
)
.
argName
(
"bootrom
.kc
"
)
.
argName
(
"bootrom"
)
.
hasArg
()
.
hasArg
()
.
numberOfArgs
(
8
)
.
numberOfArgs
(
8
)
.
build
()
.
build
()
...
...
src/main/java/me/felinewith/kcpu/hardware/Kmcu.java
View file @
78af4d1
package
me
.
felinewith
.
kcpu
.
hardware
;
package
me
.
felinewith
.
kcpu
.
hardware
;
import
me.felinewith.kcpu.hardware.kmcu.KmcuOp
;
import
java.io.PrintStream
;
import
java.io.PrintStream
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
me.felinewith.kcpu.
util.Converter
;
import
me.felinewith.kcpu.
hardware.kmcu.KmcuOp
;
import
me.felinewith.kcpu.util.BaseDevice
;
import
me.felinewith.kcpu.util.BaseDevice
;
import
me.felinewith.kcpu.util.Converter
;
/**
/**
*
*
...
@@ -38,11 +38,6 @@ public class Kmcu extends BaseDevice {
...
@@ -38,11 +38,6 @@ public class Kmcu extends BaseDevice {
name
=
"Kmcp"
;
name
=
"Kmcp"
;
}
}
@Override
public
void
exec
()
{
workInit
((
short
)
0
);
workInit
((
short
)
1
);
}
private
void
workInit
(
short
setting
)
{
private
void
workInit
(
short
setting
)
{
byte
[]
reg
;
byte
[]
reg
;
if
(
setting
==
0
)
{
reg
=
Arrays
.
copyOfRange
(
memory
,
0
,
7
);
}
if
(
setting
==
0
)
{
reg
=
Arrays
.
copyOfRange
(
memory
,
0
,
7
);
}
...
@@ -465,9 +460,15 @@ public class Kmcu extends BaseDevice {
...
@@ -465,9 +460,15 @@ public class Kmcu extends BaseDevice {
return
output
;
return
output
;
}
}
@Override
public
void
memIrq
(
short
addr
)
{
@Override
public
void
memIrq
(
short
addr
,
byte
irq
)
{
if
(
0
<=
addr
&&
addr
<=
memory
.
length
)
{
exec
();
}
if
(
0
<=
addr
&&
addr
<=
memory
.
length
)
{
workInit
((
short
)
0
);
workInit
((
short
)
1
);
}
}
}
@Override
public
void
sendIrq
(
byte
irq
)
{
}
@Override
public
void
recvIrq
(
byte
irq
)
{
workInit
((
short
)
0
);
workInit
((
short
)
1
);
}
}
}
src/main/java/me/felinewith/kcpu/interfaces/IDevice.java
View file @
78af4d1
...
@@ -8,5 +8,5 @@ public interface IDevice extends IMemory {
...
@@ -8,5 +8,5 @@ public interface IDevice extends IMemory {
public
void
init
(
IMemory
board
);
public
void
init
(
IMemory
board
);
public
abstract
void
sendIrq
(
byte
irq
);
public
abstract
void
sendIrq
(
byte
irq
);
public
void
exec
(
);
public
abstract
void
recvIrq
(
byte
irq
);
}
}
src/main/java/me/felinewith/kcpu/interfaces/IMemory.java
View file @
78af4d1
...
@@ -8,8 +8,7 @@ public interface IMemory {
...
@@ -8,8 +8,7 @@ public interface IMemory {
public
abstract
short
length
();
public
abstract
short
length
();
public
abstract
byte
read
(
short
addr
);
public
abstract
byte
read
(
short
addr
);
public
abstract
void
write
(
short
addr
,
byte
data
);
public
abstract
void
write
(
short
addr
,
byte
data
);
public
void
copy
(
short
addrSrc
,
short
addrDest
,
IMemory
dest
);
public
abstract
void
memIrq
(
short
addr
,
byte
irq
);
public
abstract
void
memIrq
(
short
addr
);
public
void
powerOff
();
public
void
powerOff
();
}
}
src/main/java/me/felinewith/kcpu/memory/BootRom.java
View file @
78af4d1
...
@@ -6,6 +6,7 @@ import java.io.FileNotFoundException;
...
@@ -6,6 +6,7 @@ import java.io.FileNotFoundException;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
me.felinewith.kcpu.Kasm
;
import
me.felinewith.kcpu.Kasm
;
import
me.felinewith.kcpu.Kasm.KasmBuilder
;
import
me.felinewith.kcpu.util.BaseMemory
;
import
me.felinewith.kcpu.util.BaseMemory
;
/**
/**
...
@@ -15,42 +16,42 @@ import me.felinewith.kcpu.util.BaseMemory;
...
@@ -15,42 +16,42 @@ import me.felinewith.kcpu.util.BaseMemory;
public
class
BootRom
extends
BaseMemory
{
public
class
BootRom
extends
BaseMemory
{
private
short
writepos
;
private
short
writepos
;
private
short
prev
;
private
short
prev2
;
private
boolean
writable
;
private
boolean
writable
;
public
BootRom
()
{
public
BootRom
()
{
writepos
=
0
;
writepos
=
0
;
prev
=
0
;
writable
=
true
;
prev2
=
0
;
writable
=
false
;
memory
=
new
byte
[
0x1000
];
memory
=
new
byte
[
0x1000
];
Arrays
.
fill
(
memory
,
(
byte
)
0xff
);
Arrays
.
fill
(
memory
,
(
byte
)
0xff
);
KasmBuilder
kb
=
Kasm
.
builder
();
kb
.
setBASEaddr
((
short
)
0x1000
);
kb
.
setVerbose
(
false
);
Kasm
kasm
=
kb
.
build
();
// hardcoding some bootrom
// hardcoding some bootrom
writeBytes
(
Kasm
.
compile
(
"movs $0 r2"
));
//writeBytes(kasm.compileSegment("movs $0 r2"));
writeBytes
(
Kasm
.
compile
(
"add r0 16"
));
kasm
.
compileSegment
(
"mark"
);
writeBytes
(
Kasm
.
compile
(
"add r2 1"
));
writeBytes
(
kasm
.
compileSegment
(
"add r0 16"
));
writeBytes
(
Kasm
.
compile
(
"movs $0 r2"
));
writeBytes
(
kasm
.
compileSegment
(
"add r2 1"
));
writeBytes
(
Kasm
.
compile
(
"jdl r0 512 22,16"
));
writeBytes
(
kasm
.
compileSegment
(
"movs $0 r2"
));
writeBytes
(
kasm
.
compileSegment
(
"jdl r0 512 mark"
));
//writeBytes(Kasm.compile("movs r0 0"));
//writeBytes(Kasm.compile("movs r0 0"));
//writeBytes(Kasm.compile("movs r1 0"));
//writeBytes(Kasm.compile("movs r1 0"));
//writeBytes(Kasm.compile("movs r2 0"));
//writeBytes(Kasm.compile("movs r2 0"));
//writeBytes(Kasm.compile("movs r3 0"));
//writeBytes(Kasm.compile("movs r3 0"));
writeBytes
(
Kasm
.
compile
(
"gpc %0300,16
"
));
writeBytes
(
kasm
.
compileSegment
(
"gpc
"
));
writeBytes
(
Kasm
.
compile
(
"mov ff00,16 61,16"
));
writeBytes
(
kasm
.
compileSegment
(
"mov ff00,16 61,16"
));
writeBytes
(
Kasm
.
compile
(
"irqm ff01,16"
));
writeBytes
(
kasm
.
compileSegment
(
"irqm ff01,16"
));
}
}
@Override
public
void
memIrq
(
short
addr
)
{
// writable at the start, so smart ROMs can rewrite themselves to rearrange stuff
writable
=
((
prev2
==
0x4b63
)
&&
(
prev
==
0x7075
)
&&
(
addr
==
0x7f
));
// useful for moving devices around the address space at boot-time
// then a simple program can write a device table into ROM space
if
((
0xff
&
prev
)
==
0
)
{
prev
+=
addr
;
}
// finally, send an interrupt to the ROM device to lock it
else
if
((
0xff00
&
prev
)
==
0
)
{
prev
=
(
short
)(
prev
<<
8
);
prev
+=
addr
;
}
@Override
public
void
memIrq
(
short
addr
,
byte
irq
)
{
writable
=
false
;
}
else
{
prev2
=
prev
;
}
}
@Override
public
void
write
(
short
addr
,
byte
data
)
{
@Override
public
void
write
(
short
addr
,
byte
data
)
{
if
(!
writable
)
{
return
;
}
if
(!
writable
)
{
return
;
}
...
...
src/main/java/me/felinewith/kcpu/memory/Buffer.java
View file @
78af4d1
...
@@ -40,7 +40,7 @@ public class Buffer extends BaseMemory {
...
@@ -40,7 +40,7 @@ public class Buffer extends BaseMemory {
bufout
=
new
OutputStreamWriter
(
stdout
);
bufout
=
new
OutputStreamWriter
(
stdout
);
}
}
@Override
public
void
memIrq
(
short
addr
)
{
@Override
public
void
memIrq
(
short
addr
,
byte
irq
)
{
short
a
;
short
a
;
short
value
;
short
value
;
if
(
addr
<=
0x0f
)
{
if
(
addr
<=
0x0f
)
{
...
...
src/main/java/me/felinewith/kcpu/opcodes/Memory.java
View file @
78af4d1
package
me
.
felinewith
.
kcpu
.
opcodes
;
package
me
.
felinewith
.
kcpu
.
opcodes
;
import
me.felinewith.kcpu.util.helpers.ValueHelper
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
me.felinewith.kcpu.interfaces.IMemory
;
import
me.felinewith.kcpu.interfaces.IMemory
;
import
me.felinewith.kcpu.util.helpers.ValueHelper
;
/**
/**
*
*
...
@@ -11,8 +11,9 @@ import me.felinewith.kcpu.interfaces.IMemory;
...
@@ -11,8 +11,9 @@ import me.felinewith.kcpu.interfaces.IMemory;
public
class
Memory
implements
IOpcodeHandler
{
public
class
Memory
implements
IOpcodeHandler
{
@Override
public
short
[]
opcode
(
OpDirector
opcode
,
short
pc
,
short
ref
,
short
[]
regs
,
short
[]
values
,
IMemory
memory
)
{
@Override
public
short
[]
opcode
(
OpDirector
opcode
,
short
pc
,
short
ref
,
short
[]
regs
,
short
[]
values
,
IMemory
memory
)
{
short
data
;
short
[]
output
=
Arrays
.
copyOf
(
regs
,
regs
.
length
);
short
[]
output
=
Arrays
.
copyOf
(
regs
,
regs
.
length
);
short
addr
=
ValueHelper
.
readShort
(
0
,
ref
,
output
,
values
,
memory
);
short
data
;
switch
(
opcode
)
{
switch
(
opcode
)
{
case
MOV:
case
MOVB:
case
MOV:
case
MOVB:
data
=
ValueHelper
.
readByte
(
1
,
ref
,
output
,
values
,
memory
);
data
=
ValueHelper
.
readByte
(
1
,
ref
,
output
,
values
,
memory
);
...
...
src/main/java/me/felinewith/kcpu/opcodes/OpDirector.java
View file @
78af4d1
...
@@ -18,43 +18,59 @@ public enum OpDirector {
...
@@ -18,43 +18,59 @@ public enum OpDirector {
MOV
(
0x0010
,
Memory
.
class
,
"Alias for MOVB"
),
MOVB
(
0x0010
,
Memory
.
class
,
"dest value"
),
MOV
(
0x0010
,
Memory
.
class
,
"Alias for MOVB"
),
MOVB
(
0x0010
,
Memory
.
class
,
"dest value"
),
MOVS
(
0x0011
,
Memory
.
class
,
"dest value"
),
MOVS
(
0x0011
,
Memory
.
class
,
"dest value"
),
// stack manipulation
PUSH
(
0x1000
,
"value: push value to stack"
),
POP
(
0x1001
,
"pop value off stack"
),
CALL
(
0x1002
,
"addr: call function at address"
),
RET
(
0x1003
,
"return from function"
),
IRET
(
0x10f0
,
"return from interrupt state (does nothing in normal mode)"
),
// interrupt vector management
IVEC
(
0x10f1
,
"irq addr: set function address for interrupt irq"
),
// cpu stuffies
// cpu stuffies
DEVA
(
0xff00
,
"
n0; get device at address n0
"
),
// get device port from address
DEVA
(
0xff00
,
"
addr; get device at address
"
),
// get device port from address
DEVD
(
0xff01
,
"
n0: detach device on port n0
"
),
// detach device
DEVD
(
0xff01
,
"
port: detach device on port
"
),
// detach device
DEVM
(
0xff02
,
"
n0 n1: relocate device n0 to address n1
"
),
// relocate device
DEVM
(
0xff02
,
"
port newaddr: relocate device to address
"
),
// relocate device
DEVP
(
0x1003
,
"
n0: get device address for device on port n0
"
),
// get device address from port
DEVP
(
0x1003
,
"
port: get device address for device on port
"
),
// get device address from port
IRQD
(
0xff10
,
"n0: send interrupt to port n0"
),
// interrupt to port
// interrupts
IRQM
(
0xff11
,
"n0: send interrupt to memory address n0"
),
// interrupt to memory
IRQD
(
0xff10
,
"port: send interrupt to port"
),
// interrupt to port
IRQM
(
0xff11
,
"addr: send interrupt to memory address"
),
// interrupt to memory
// jumps
JMP
(
0xff18
,
"Alias of JMPU"
),
// jump up
JMP
(
0xff18
,
"Alias of JMPU"
),
// jump up
JMPU
(
0xff18
,
"
n0
: jump up n0 addresses"
),
JMPU
(
0xff18
,
"
addr
: jump up n0 addresses"
),
JMPA
(
0xff19
,
"
n0
: jump to address n0"
),
// jump absolute addr
JMPA
(
0xff19
,
"
addr
: jump to address n0"
),
// jump absolute addr
JMPD
(
0xff1a
,
"
n0
: jump down n0 addresses"
),
// jump down
JMPD
(
0xff1a
,
"
addr
: jump down n0 addresses"
),
// jump down
GPC
(
0xff1b
,
"write instruction pointer"
),
// get instruction pointer
GPC
(
0xff1b
,
"write instruction pointer"
),
// get instruction pointer
// comparisson jumps
JE
(
0xff20
,
"Alias of JUE"
),
// jump if =
JE
(
0xff20
,
"Alias of JUE"
),
// jump if =
JUE
(
0xff20
,
"n0 n1
n2
: jump if n0 == n1, see JMPU"
),
JUE
(
0xff20
,
"n0 n1
addr
: jump if n0 == n1, see JMPU"
),
JAE
(
0xff21
,
"n0 n1
n2
: jump if n0 == n1, see JMPA"
),
JAE
(
0xff21
,
"n0 n1
addr
: jump if n0 == n1, see JMPA"
),
JDE
(
0xff22
,
"n0 n1
n2
: jump if n0 == n1, see JMPD"
),
JDE
(
0xff22
,
"n0 n1
addr
: jump if n0 == n1, see JMPD"
),
JG
(
0xff23
,
"Alias of JUG"
),
// jump if >
JG
(
0xff23
,
"Alias of JUG"
),
// jump if >
JUG
(
0xff23
,
"n0 n1
n2
: jump if n0 > n1, see JMPU"
),
JUG
(
0xff23
,
"n0 n1
addr
: jump if n0 > n1, see JMPU"
),
JAG
(
0xff24
,
"n0 n1
n2
: jump if n0 > n1, see JMPA"
),
JAG
(
0xff24
,
"n0 n1
addr
: jump if n0 > n1, see JMPA"
),
JDG
(
0xff25
,
"n0 n1
n2
: jump if n0 > n1, see JMPD"
),
JDG
(
0xff25
,
"n0 n1
addr
: jump if n0 > n1, see JMPD"
),
JL
(
0xff26
,
"Alias of JUL"
),
// jump if <
JL
(
0xff26
,
"Alias of JUL"
),
// jump if <
JUL
(
0xff26
,
"n0 n1
n2
: jump if n0 < n1, see JMPU"
),
JUL
(
0xff26
,
"n0 n1
addr
: jump if n0 < n1, see JMPU"
),
JAL
(
0xff27
,
"n0 n1
n2
: jump if n0 < n1, see JMPA"
),
JAL
(
0xff27
,
"n0 n1
addr
: jump if n0 < n1, see JMPA"
),
JDL
(
0xff28
,
"n0 n1
n2
: jump if n0 < n1, see JMPD"
),
JDL
(
0xff28
,
"n0 n1
addr
: jump if n0 < n1, see JMPD"
),
JGE
(
0xff29
,
"Alias of JUGE"
),
// jump if >=
JGE
(
0xff29
,
"Alias of JUGE"
),
// jump if >=
JUGE
(
0xff29
,
"n0 n1
n2
: jump if n0 >= n1, see JMPU"
),
JUGE
(
0xff29
,
"n0 n1
addr
: jump if n0 >= n1, see JMPU"
),
JAGE
(
0xff2a
,
"n0 n1
n2
: jump if n0 >= n1, see JMPA"
),
JAGE
(
0xff2a
,
"n0 n1
addr
: jump if n0 >= n1, see JMPA"
),
JDGE
(
0xff2b
,
"n0 n1
n2
: jump if n0 >= n1, see JMPD"
),
JDGE
(
0xff2b
,
"n0 n1
addr
: jump if n0 >= n1, see JMPD"
),
JLE
(
0xff2c
,
"Alias of JULE"
),
// jump if <=
JLE
(
0xff2c
,
"Alias of JULE"
),
// jump if <=
JULE
(
0xff2c
,
"n0 n1 n2: jump if n0 <= n1, see JMPU"
),
JULE
(
0xff2c
,
"n0 n1 addr: jump if n0 <= n1, see JMPU"
),
JALE
(
0xff2d
,
"n0 n1 n2: jump if n0 <= n1, see JMPA"
),
JALE
(
0xff2d
,
"n0 n1 addr: jump if n0 <= n1, see JMPA"
),
JDLE
(
0xff2e
,
"n0 n1 n2: jump if n0 <= n1, see JMPD"
),
JDLE
(
0xff2e
,
"n0 n1 addr: jump if n0 <= n1, see JMPD"
),
// value compare
VCMP
(
0xff2f
,
"n0 n1: performs multiple comparissons of n0 and n1"
),
VCMP
(
0xff2f
,
"n0 n1: performs multiple comparissons of n0 and n1"
),
// power
ZPWR
(
0xffff
,
"Power off"
),
// power off
ZPWR
(
0xffff
,
"Power off"
),
// power off
;
;
...
...
src/main/java/me/felinewith/kcpu/util/BaseDevice.java
View file @
78af4d1
...
@@ -16,16 +16,13 @@ public abstract class BaseDevice extends BaseMemory implements IDevice {
...
@@ -16,16 +16,13 @@ public abstract class BaseDevice extends BaseMemory implements IDevice {
board
=
system
;
board
=
system
;
}
}
@Override
public
void
memIrq
(
short
addr
)
{
if
(
0
<=
addr
&&
addr
<=
memory
.
length
)
{
exec
();
}
}
protected
void
sendIrq
()
{
protected
void
sendIrq
()
{
int
addr
=
memory
.
length
-
1
;
int
addr
=
memory
.
length
-
1
;
sendIrq
(
memory
[
addr
]);
sendIrq
(
memory
[
addr
]);
}
}
@Override
public
void
sendIrq
(
byte
irq
)
{
}
@Override
public
void
sendIrq
(
byte
irq
)
{
}
@Override
public
void
recvIrq
(
byte
irq
)
{
}
@Override
public
short
length
()
{
return
(
short
)
memory
.
length
;
}
@Override
public
short
length
()
{
return
(
short
)
memory
.
length
;
}
...
...
src/main/java/me/felinewith/kcpu/util/BaseMemory.java
View file @
78af4d1
...
@@ -26,13 +26,7 @@ public abstract class BaseMemory implements IMemory {
...
@@ -26,13 +26,7 @@ public abstract class BaseMemory implements IMemory {
memory
[
0xffff
&
addr
]
=
data
;
memory
[
0xffff
&
addr
]
=
data
;
}
}
public
final
void
copy
(
int
addrSrc
,
int
addrDest
,
IMemory
dest
)
{
copy
((
short
)
addrSrc
,
(
short
)
addrDest
,
dest
);
}
@Override
public
void
memIrq
(
short
addr
,
byte
irq
)
{
}
@Override
public
void
copy
(
short
addrSrc
,
short
addrDest
,
IMemory
dest
)
{
if
(
(
0xffff
&
addrSrc
)
>
length
()
)
{
return
;
}
dest
.
write
(
addrDest
,
read
(
addrSrc
));
}
@Override
public
void
memIrq
(
short
addr
)
{
}
@Override
public
void
powerOff
()
{
}
@Override
public
void
powerOff
()
{
}
}
}
src/main/java/me/felinewith/kcpu/util/CPUStoppedException.java
0 → 100644
View file @
78af4d1
package
me
.
felinewith
.
kcpu
.
util
;
/**
*
* @author jlhawkwell
*/
public
class
CPUStoppedException
extends
Exception
{
/**
* Creates a new instance of <code>CPUStoppedException</code> without detail message.
*/
public
CPUStoppedException
()
{
}
/**
* Constructs an instance of <code>CPUStoppedException</code> with the specified detail message.
*
* @param msg the detail message.
*/
public
CPUStoppedException
(
String
msg
)
{
super
(
msg
);
}
}
src/main/java/me/felinewith/kcpu/util/HardwareExec.java
deleted
100644 → 0
View file @
c44caf9
package
me
.
felinewith
.
kcpu
.
util
;
import
java.util.TimerTask
;
import
me.felinewith.kcpu.interfaces.IDevice
;
/**
*
* @author jlhawkwell
*/
public
class
HardwareExec
extends
TimerTask
{
IDevice
id
;
public
HardwareExec
(
IDevice
device
)
{
id
=
device
;
}
@Override
public
void
run
()
{
id
.
exec
();
}
}
src/main/java/me/felinewith/kcpu/util/HardwareMemIrq.java
View file @
78af4d1
...
@@ -11,10 +11,15 @@ public class HardwareMemIrq extends TimerTask {
...
@@ -11,10 +11,15 @@ public class HardwareMemIrq extends TimerTask {
IMemory
id
;
IMemory
id
;
short
a
;
short
a
;
byte
i
;
public
HardwareMemIrq
(
IMemory
device
,
short
addr
)
{
public
HardwareMemIrq
(
IMemory
device
,
short
addr
,
byte
irq
)
{
id
=
device
;
id
=
device
;
a
=
addr
;
a
=
addr
;
i
=
irq
;
}
@Override
public
void
run
()
{
Thread
.
currentThread
().
setName
(
String
.
format
(
"memIRQ-%02x-%x"
,
id
,
Thread
.
currentThread
().
getId
()
));
id
.
memIrq
(
a
,
i
);
}
}
@Override
public
void
run
()
{
id
.
memIrq
(
a
);
}
}
}
src/main/java/me/felinewith/kcpu/util/Hardware
Send
Irq.java
→
src/main/java/me/felinewith/kcpu/util/Hardware
Recv
Irq.java
View file @
78af4d1
...
@@ -7,14 +7,17 @@ import me.felinewith.kcpu.interfaces.IDevice;
...
@@ -7,14 +7,17 @@ import me.felinewith.kcpu.interfaces.IDevice;
*
*
* @author jlhawkwell
* @author jlhawkwell
*/
*/
public
class
Hardware
Send
Irq
extends
TimerTask
{
public
class
Hardware
Recv
Irq
extends
TimerTask
{
IDevice
id
;
IDevice
id
;
byte
i
;
byte
i
;
public
Hardware
Send
Irq
(
IDevice
device
,
byte
irq
)
{
public
Hardware
Recv
Irq
(
IDevice
device
,
byte
irq
)
{
id
=
device
;
id
=
device
;
i
=
irq
;
i
=
irq
;
}
}
@Override
public
void
run
()
{
id
.
sendIrq
(
i
);
}
@Override
public
void
run
()
{
Thread
.
currentThread
().
setName
(
String
.
format
(
"recvIRQ-%02x_%02x-%x"
,
id
,
i
,
Thread
.
currentThread
().
getId
()
));
id
.
recvIrq
(
i
);
}
}
}
src/main/java/me/felinewith/kcpu/util/helpers/ValueHelper.java
View file @
78af4d1
...
@@ -25,6 +25,7 @@ public class ValueHelper {
...
@@ -25,6 +25,7 @@ public class ValueHelper {
case
2
:
cref
=
(
short
)(
0x0030
&
ref
);
break
;
case
2
:
cref
=
(
short
)(
0x0030
&
ref
);
break
;
case
3
:
cref
=
(
short
)(
0x00c0
&
ref
);
break
;
case
3
:
cref
=
(
short
)(
0x00c0
&
ref
);
break
;
}
}
switch
(
cref
)
{
switch
(
cref
)
{
case
0x0000
:
output
=
values
[
pos
];
break
;
case
0x0000
:
output
=
values
[
pos
];
break
;
case
0x0001
:
case
0x0004
:
case
0x0010
:
case
0x0040
:
case
0x0001
:
case
0x0004
:
case
0x0010
:
case
0x0040
:
...
@@ -55,10 +56,14 @@ public class ValueHelper {
...
@@ -55,10 +56,14 @@ public class ValueHelper {
case
2
:
cref
=
(
short
)(
0x0030
&
ref
);
break
;
case
2
:
cref
=
(
short
)(
0x0030
&
ref
);
break
;
case
3
:
cref
=
(
short
)(
0x00c0
&
ref
);
break
;
case
3
:
cref
=
(
short
)(
0x00c0
&
ref
);
break
;
}
}
// short-circuit write to register if position isn't used in the instruction
if
(
pos
>
((
0x0f00
&
reg
)
>>
8
))
{
cref
=
1
;
}
switch
(
cref
)
{
switch
(
cref
)
{
case
0x0000
:
case
0x0001
:
case
0x0004
:
case
0x0010
:
case
0x0040
:
case
0x0001
:
case
0x0004
:
case
0x0010
:
case
0x0040
:
output
[
reg
]
=
data
;
break
;
output
[
reg
]
=
data
;
break
;
case
0x0000
:
case
0x0002
:
case
0x0008
:
case
0x0020
:
case
0x0080
:
case
0x0002
:
case
0x0008
:
case
0x0020
:
case
0x0080
:
MemHelper
.
writeByte
(
values
[
pos
],
data
,
memory
);
break
;
MemHelper
.
writeByte
(
values
[
pos
],
data
,
memory
);
break
;
case
0x0003
:
case
0x000c
:
case
0x0030
:
case
0x00c0
:
case
0x0003
:
case
0x000c
:
case
0x0030
:
case
0x00c0
:
...
@@ -109,10 +114,16 @@ public class ValueHelper {
...
@@ -109,10 +114,16 @@ public class ValueHelper {
case
2
:
cref
=
(
short
)(
0x0030
&
ref
);
break
;
case
2
:
cref
=
(
short
)(
0x0030
&
ref
);
break
;
case
3
:
cref
=
(
short
)(
0x00c0
&
ref
);
break
;
case
3
:
cref
=
(
short
)(
0x00c0
&
ref
);
break
;
}
}
// short-circuit write to register if position isn't used in the instruction
if
(
pos
>
((
0x0f00
&
ref
)
>>
8
))
{
cref
=
1
;
}
switch
(
cref
)
{
switch
(
cref
)
{
case
0x0000
:
case
0x0001
:
case
0x0004
:
case
0x0010
:
case
0x0040
:
case
0x0001
:
case
0x0004
:
case
0x0010
:
case
0x0040
:
output
[
reg
]
=
data
;
break
;
output
[
reg
]
=
data
;
break
;
case
0x0000
:
case
0x0002
:
case
0x0008
:
case
0x0020
:
case
0x0080
:
case
0x0002
:
case
0x0008
:
case
0x0020
:
case
0x0080
:
MemHelper
.
writeShort
(
values
[
pos
],
data
,
memory
);
break
;
MemHelper
.
writeShort
(
values
[
pos
],
data
,
memory
);
break
;
case
0x0003
:
case
0x000c
:
case
0x0030
:
case
0x00c0
:
case
0x0003
:
case
0x000c
:
case
0x0030
:
case
0x00c0
:
...
...
src/main/java/me/felinewith/kcpu/util/helpers/ValueType.java
View file @
78af4d1
...
@@ -10,8 +10,8 @@ public enum ValueType {
...
@@ -10,8 +10,8 @@ public enum ValueType {
AD
(
2
),
AD
(
2
),
AR
(
3
);
AR
(
3
);
in
t
t
;
shor
t
t
;
private
ValueType
(
int
type
)
{
t
=
type
;
}
private
ValueType
(
int
type
)
{
t
=
(
short
)
type
;
}
public
static
ValueType
valueOf
(
int
value
,
int
position
)
{
public
static
ValueType
valueOf
(
int
value
,
int
position
)
{
int
temp
=
value
>>
(
position
*
2
);
int
temp
=
value
>>
(
position
*
2
);
...
@@ -24,5 +24,5 @@ public enum ValueType {
...
@@ -24,5 +24,5 @@ public enum ValueType {
}
}
return
D
;
return
D
;
}
}
public
in
t
getValue
()
{
return
t
;
}
public
shor
t
getValue
()
{
return
t
;
}
}
}
test.kasm
View file @
78af4d1
...
@@ -2,9 +2,9 @@ movs $0 r2
...
@@ -2,9 +2,9 @@ movs $0 r2
add r0 16
add r0 16
add r2 1
add r2 1
movs $0 r2
movs $0 r2
jdl r0 512 2a,16
jdl r0 512 2
0,16+
a,16
deva 0
deva 0
deva 1
deva 1
gpc
gpc
gpc %300,16
gpc %
100,16+
300,16
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment