Add support for K1 and K2 declarations to microcompiler

This commit is contained in:
Gabriel Tofvesson 2019-04-24 19:46:42 +02:00
parent 60b1278f6a
commit aa13da3219

View File

@ -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
@ -422,6 +431,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
@ -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)
}