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 } }