Add support for K1 and K2 declarations to microcompiler
This commit is contained in:
parent
60b1278f6a
commit
aa13da3219
@ -194,27 +194,33 @@ class AddressReference{
|
|||||||
|
|
||||||
private constructor(address: Int?, labelName: String?){
|
private constructor(address: Int?, labelName: String?){
|
||||||
this.address = address ?: -1
|
this.address = address ?: -1
|
||||||
actualAddress = this.address
|
_actualAddress = this.address
|
||||||
this.labelName = labelName
|
this.labelName = labelName
|
||||||
if(address == null && labelName == null) throw RuntimeException("Reference must be accessible by name or address")
|
if(address == null && labelName == null) throw RuntimeException("Reference must be accessible by name or address")
|
||||||
}
|
}
|
||||||
|
|
||||||
var actualAddress: Int
|
val actualAddress: Int
|
||||||
private set
|
get() {
|
||||||
|
if(_actualAddress == -1)
|
||||||
|
throw RuntimeException("Unresolved label reference: $labelName")
|
||||||
|
return _actualAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
private var _actualAddress: Int
|
||||||
|
|
||||||
private fun checkResolved(){
|
private fun checkResolved(){
|
||||||
if(actualAddress != -1) throw RuntimeException("Address already resolved")
|
if(_actualAddress != -1) throw RuntimeException("Address already resolved")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun resolveConstant(value: Int){
|
fun resolveConstant(value: Int){
|
||||||
checkResolved()
|
checkResolved()
|
||||||
actualAddress = value
|
_actualAddress = value
|
||||||
}
|
}
|
||||||
|
|
||||||
fun resolveAddress(target: Int){
|
fun resolveAddress(target: Int){
|
||||||
if(target > 128 || target < 0) throw RuntimeException("Invalid target address")
|
if(target > 128 || target < 0) throw RuntimeException("Invalid target address")
|
||||||
checkResolved()
|
checkResolved()
|
||||||
actualAddress = target
|
_actualAddress = target
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -378,6 +384,9 @@ fun main(args: Array<String>){
|
|||||||
var currentLine = 0
|
var currentLine = 0
|
||||||
var lineCount = 0
|
var lineCount = 0
|
||||||
val insns = ArrayList<MicroInstruction>()
|
val insns = ArrayList<MicroInstruction>()
|
||||||
|
val k1 = HashMap<Int, AddressReference>()
|
||||||
|
val k2 = HashMap<Int, AddressReference>()
|
||||||
|
|
||||||
println("@p")
|
println("@p")
|
||||||
for(line in file.readText().replace("\r", "").split("\n")){
|
for(line in file.readText().replace("\r", "").split("\n")){
|
||||||
++lineCount
|
++lineCount
|
||||||
@ -423,6 +432,44 @@ fun main(args: Array<String>){
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Define optable (k1) entry
|
||||||
|
if(actualCode.startsWith("#optable ")){
|
||||||
|
// Parse K1 declaration
|
||||||
|
val substr = actualCode.substring(9)
|
||||||
|
if(substr.indexOf(" ") == -1) throw RuntimeException("Bad optable declaration: $actualCode")
|
||||||
|
|
||||||
|
val address = substr.substring(0, substr.indexOf(" "))
|
||||||
|
val constant = substr.substring(substr.indexOf(" ") + 1).replace(" ", "").replace("\t", "")
|
||||||
|
|
||||||
|
try{
|
||||||
|
k1[readNumber(address, 0xF)] =
|
||||||
|
if(constant.startsWith("@")) AddressReference.makeReference(constant.substring(1))
|
||||||
|
else AddressReference.makeReference(readNumber(constant, 127))
|
||||||
|
}catch(e: NumberFormatException){
|
||||||
|
throw RuntimeException("Unknown number format for optable declaration: $actualCode")
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define addressing mode (k2) entry
|
||||||
|
if(actualCode.startsWith("#amode ")){
|
||||||
|
// Parse K2 declarationa
|
||||||
|
val substr = actualCode.substring(7)
|
||||||
|
if(substr.indexOf(" ") == -1) throw RuntimeException("Bad amode declaration: $actualCode")
|
||||||
|
|
||||||
|
val address = substr.substring(0, substr.indexOf(" "))
|
||||||
|
val constant = substr.substring(substr.indexOf(" ") + 1).replace(" ", "").replace("\t", "")
|
||||||
|
|
||||||
|
try{
|
||||||
|
k2[readNumber(address, 0x3)] =
|
||||||
|
if(constant.startsWith("@")) AddressReference.makeReference(constant.substring(1))
|
||||||
|
else AddressReference.makeReference(readNumber(constant, 127))
|
||||||
|
}catch(e: NumberFormatException){
|
||||||
|
throw RuntimeException("Unknown number format for amode declaration: $actualCode")
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
val instr = parseInstruction(actualCode)
|
val instr = parseInstruction(actualCode)
|
||||||
if(instr == null) continue // Blank line
|
if(instr == null) continue // Blank line
|
||||||
insns.add(instr)
|
insns.add(instr)
|
||||||
@ -437,12 +484,27 @@ fun main(args: Array<String>){
|
|||||||
System.exit(1)
|
System.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
System.err.println("INFO: Microcompilation succeeded! Instruction count: $currentLine")
|
// Convert instructions to strings
|
||||||
|
// Also resolve address references here
|
||||||
for(instr in insns)
|
for(instr in insns)
|
||||||
builder.append(instr.compiledValue.toInstruction()).append("\n")
|
builder.append(instr.compiledValue.toInstruction()).append("\n")
|
||||||
|
|
||||||
|
// Write K-table data ahead of instructions
|
||||||
|
for(k1Pair in k1)
|
||||||
|
println("@k1${k1Pair.key.toString(16)}${k1Pair.value.actualAddress.toPaddedHexString(2)}")
|
||||||
|
|
||||||
|
for(k2Pair in k2)
|
||||||
|
println("@k2${k2Pair.key.toString(16)}${k2Pair.value.actualAddress.toPaddedHexString(2)}")
|
||||||
|
|
||||||
|
// Write instructions
|
||||||
print(builder.toString())
|
print(builder.toString())
|
||||||
|
|
||||||
|
// Informational message
|
||||||
|
System.err.println("INFO: Microcompilation succeeded! Instruction count: $currentLine")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun Int.toPaddedHexString(len: Int): String {
|
||||||
|
val str = toString(16)
|
||||||
|
return if(str.length >= len) str else ("0".repeat(len - str.length) + str)
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user