66 lines
2.8 KiB
TypeScript
66 lines
2.8 KiB
TypeScript
import bit from "./bit";
|
|
import { memory } from "./memory";
|
|
import { Ram, ram } from "./ram";
|
|
import { Word, emptyWord, wordFromNumber, wordFromString } from "./word";
|
|
|
|
const bank1GeneralAddressesStart = wordFromString("0010") as Word<4>
|
|
const bank2GeneralAddressesStart = wordFromString("0101") as Word<4>
|
|
|
|
const addressRegisterAddress = wordFromString("0000") as Word<4>
|
|
const extendedAddressRegisterAddress = wordFromString("0001") as Word<4>
|
|
|
|
const programCounterAddress = wordFromString("0010") as Word<4>
|
|
const overflowFlagAddress = wordFromString("0011") as Word<4>
|
|
const inputPinAddress = wordFromString("0100") as Word<4>
|
|
|
|
|
|
export function minecraftMachine(initialBank1Values: Word<4>[], initialBank2Values: Word<4>[], instructions: Word<4>[]) {
|
|
|
|
const bank1Ram = ram({ size: 16, width: 4 })
|
|
const bank2Ram = ram({ size: 16, width: 4 })
|
|
const stack = ram({ size: 4, width: 4 })
|
|
const stackPointer = memory(wordFromString("00"))
|
|
const instructionPointer = memory(wordFromString("0"))
|
|
|
|
initialBank1Values.forEach((value, index) => bank1Ram.write(value, wordFromNumber(index).plus(bank1GeneralAddressesStart).sum))
|
|
initialBank2Values.forEach((value, index) => bank2Ram.write(value, wordFromNumber(index).plus(bank2GeneralAddressesStart).sum))
|
|
|
|
const addressRegister = bank1Ram.get(addressRegisterAddress)
|
|
const extendedAddressRegister = bank1Ram.get(extendedAddressRegisterAddress)
|
|
addressRegister.set(wordFromNumber(2, 4) as Word<4>)
|
|
|
|
bank2Ram.write(addressRegister.value(), addressRegisterAddress)
|
|
bank2Ram.write(extendedAddressRegister.value(), extendedAddressRegisterAddress)
|
|
|
|
|
|
const programCounter = bank2Ram.get(programCounterAddress)
|
|
const overflowFlag = bank2Ram.get(overflowFlagAddress)
|
|
const inputPin = bank2Ram.get(inputPinAddress)
|
|
|
|
function tick() {
|
|
incrementInstruction()
|
|
stack.write(readCurrent(), stackPointer.value())
|
|
|
|
if (!stackPointer.value().equals(wordFromString("11"))) {
|
|
stackPointer.set(stackPointer.value().plus(wordFromString("01")).sum)
|
|
}
|
|
|
|
addressRegister.set(addressRegister.value().plus(wordFromNumber(1, 4)).sum)
|
|
}
|
|
|
|
function incrementInstruction() {
|
|
if (instructionPointer.value().equals(wordFromString("1"))) {
|
|
programCounter.set(programCounter.value().plus(wordFromNumber(1, 4)).sum)
|
|
}
|
|
|
|
instructionPointer.set(instructionPointer.value().plus(wordFromString("1")).sum)
|
|
}
|
|
|
|
function readCurrent() {
|
|
const currentBank = extendedAddressRegister.value().toString() === "0000" ? bank1Ram : bank2Ram
|
|
return currentBank.read(addressRegister.value())
|
|
}
|
|
|
|
return { programCounter, instructionPointer, addressRegister, extendedAddressRegister, stack, stackPointer, tick, bank1Ram, bank2Ram }
|
|
}
|