diff --git a/tsvm_core/src/net/torvald/tsvm/peripheral/DrawCall.kt b/tsvm_core/src/net/torvald/tsvm/peripheral/DrawCall.kt index d64f9d2..eb6bc58 100644 --- a/tsvm_core/src/net/torvald/tsvm/peripheral/DrawCall.kt +++ b/tsvm_core/src/net/torvald/tsvm/peripheral/DrawCall.kt @@ -27,7 +27,7 @@ internal object DrawCallEnd : DrawCall { internal class GotoScanline(val line: Int) : DrawCall { override fun execute(gpu: GraphicsAdapter) { - gpu.drawCallRscanline = line + gpu.rScanline = line } } @@ -38,59 +38,46 @@ internal class JumpIfScanline( val whenGreaterThan: Int ) : DrawCall { override fun execute(gpu: GraphicsAdapter) { - if (gpu.drawCallRscanline < compare) { - if (whenLessThan != 65535) gpu.drawCallRscanline = whenLessThan - 1 + if (gpu.rScanline < compare) { + if (whenLessThan != 65535) gpu.rScanline = whenLessThan - 1 } - else if (gpu.drawCallRscanline == compare) { - if (whenEqualTo != 65535) gpu.drawCallRscanline = whenEqualTo - 1 + else if (gpu.rScanline == compare) { + if (whenEqualTo != 65535) gpu.rScanline = whenEqualTo - 1 } else { - if (whenGreaterThan != 65535) gpu.drawCallRscanline = whenGreaterThan - 1 + if (whenGreaterThan != 65535) gpu.rScanline = whenGreaterThan - 1 } } } +/** + * DrawDoubleLines: simply double the `len` parameter + */ internal class DrawCallDrawLines( - val opCount: Int, val colour: Int, - val xposLen1: Int, - val xposLen2: Int = 0, - val xposLen3: Int = 0, - val xposLen4: Int = 0, - val xposLen5: Int = 0, - val xposLen6: Int = 0, - val xposLen7: Int = 0, - val xposLen8: Int = 0 + val opCount: Int, val colour: Int, val lenMult: Int, + val xposs: IntArray, val lens: IntArray ) : DrawCall { override fun execute(gpu: GraphicsAdapter) { - TODO("Not yet implemented") + val cc = colour.toByte() + + for (k in 0 until opCount) { + for (i in xposs[k] until xposs[k] + lens[k]) gpu.framebuffer.set(gpu.rScanline * gpu.WIDTH * 1L + i, cc) + gpu.rScanline += Math.ceil(lens[k].toDouble() / gpu.WIDTH).toInt() + } } } -internal class DrawCallDrawDoubleLines( - val opCount: Int, val colour: Int, - val xposLen1: Int, - val xposLen2: Int = 0, - val xposLen3: Int = 0, - val xposLen4: Int = 0, - val xposLen5: Int = 0, - val xposLen6: Int = 0, - val xposLen7: Int = 0, - val xposLen8: Int = 0 -) : DrawCall { - override fun execute(gpu: GraphicsAdapter) { - TODO("Not yet implemented") - } -} internal class DrawCallCopyPixels( val opCount: Int, + val addrFrom: Int, val xPos: Int, val lineLength: Int, val stride1: Int, - val stride2: Int = 0, - val stride3: Int = 0, - val stride4: Int = 0, - val stride5: Int = 0, + val stride2: Int, + val stride3: Int, + val stride4: Int, + val stride5: Int ) : DrawCall { override fun execute(gpu: GraphicsAdapter) { TODO("Not yet implemented") diff --git a/tsvm_core/src/net/torvald/tsvm/peripheral/GraphicsAdapter.kt b/tsvm_core/src/net/torvald/tsvm/peripheral/GraphicsAdapter.kt index 18458fc..633fe73 100644 --- a/tsvm_core/src/net/torvald/tsvm/peripheral/GraphicsAdapter.kt +++ b/tsvm_core/src/net/torvald/tsvm/peripheral/GraphicsAdapter.kt @@ -354,7 +354,114 @@ open class GraphicsAdapter(private val assetsRoot: String, val vm: VM, val confi private var drawCallSize = 0 private val drawCallBuffer = Array(3640) { DrawCallEnd } internal var drawCallProgramCounter = 0 - internal var drawCallRscanline = 0 + internal var rScanline = 0 + + private fun compileWords() { + drawCallSize = 0 + while (true) { + val bytes = (0..17).map { instArea.get(18L*drawCallSize + it) }.toByteArray() + val instruction = compileWord(bytes) + drawCallBuffer[drawCallSize] = instruction + drawCallSize += 1 + + // check if the instruction contains END + if (instruction is DrawCallCompound && (instruction.call1 is DrawCallEnd || instruction.call2 is DrawCallEnd || instruction.call3 is DrawCallEnd)) { + break + } + } + } + + private fun compileWord(bytes: ByteArray): DrawCall { + val head = bytes[0] + + when (head) { + in 0..127 -> { + // D-type + when (head) { + in 0x10..0x17 -> { + return DrawCallDrawLines( + (head and 0xF).toInt() + 1, + bytes[1].toUint(), 1, + intArrayOf( + bytes[3].toUint().and(63).unzero(64), + bytes[5].toUint().and(63).unzero(64), + bytes[7].toUint().and(63).unzero(64), + bytes[9].toUint().and(63).unzero(64), + bytes[11].toUint().and(63).unzero(64), + bytes[13].toUint().and(63).unzero(64), + bytes[15].toUint().and(63).unzero(64), + bytes[17].toUint().and(63).unzero(64) + ), + intArrayOf( + bytes[2].toUint().shl(2) or bytes[3].toUint().and(192).ushr(6), + bytes[4].toUint().shl(2) or bytes[5].toUint().and(192).ushr(6), + bytes[6].toUint().shl(2) or bytes[7].toUint().and(192).ushr(6), + bytes[8].toUint().shl(2) or bytes[9].toUint().and(192).ushr(6), + bytes[10].toUint().shl(2) or bytes[11].toUint().and(192).ushr(6), + bytes[12].toUint().shl(2) or bytes[13].toUint().and(192).ushr(6), + bytes[14].toUint().shl(2) or bytes[15].toUint().and(192).ushr(6), + bytes[16].toUint().shl(2) or bytes[17].toUint().and(192).ushr(6) + ) + ) + } + in 0x18..0x1F -> { + return DrawCallDrawLines( + (head and 0xF).toInt() - 7, + bytes[1].toUint(), 2, + intArrayOf( + bytes[3].toUint().and(63).unzero(64), + bytes[5].toUint().and(63).unzero(64), + bytes[7].toUint().and(63).unzero(64), + bytes[9].toUint().and(63).unzero(64), + bytes[11].toUint().and(63).unzero(64), + bytes[13].toUint().and(63).unzero(64), + bytes[15].toUint().and(63).unzero(64), + bytes[17].toUint().and(63).unzero(64) + ), + intArrayOf( + bytes[2].toUint().shl(2) or bytes[3].toUint().and(192).ushr(6), + bytes[4].toUint().shl(2) or bytes[5].toUint().and(192).ushr(6), + bytes[6].toUint().shl(2) or bytes[7].toUint().and(192).ushr(6), + bytes[8].toUint().shl(2) or bytes[9].toUint().and(192).ushr(6), + bytes[10].toUint().shl(2) or bytes[11].toUint().and(192).ushr(6), + bytes[12].toUint().shl(2) or bytes[13].toUint().and(192).ushr(6), + bytes[14].toUint().shl(2) or bytes[15].toUint().and(192).ushr(6), + bytes[16].toUint().shl(2) or bytes[17].toUint().and(192).ushr(6) + ) + ) + } + in 0x20..0x25 -> { + return DrawCallCopyPixels( + (head and 0xF).toInt() + 1, + bytes[1].toUint().shl(16) or bytes[2].toUint().shl(8) or bytes[3].toUint(), + bytes[4].toUint().shl(8) or bytes[5].toUint(), + bytes[6].toUint().shl(8) or bytes[7].toUint(), + bytes[8].toUint().shl(8) or bytes[9].toUint(), + bytes[10].toUint().shl(8) or bytes[11].toUint(), + bytes[12].toUint().shl(8) or bytes[13].toUint(), + bytes[14].toUint().shl(8) or bytes[15].toUint(), + bytes[16].toUint().shl(8) or bytes[17].toUint() + ) + } + else -> throw UnsupportedOperationException("Unknown Head byte 0x${head.toString(16).padStart(2,'0').toUpperCase()}") + } + } + in -16..-1 -> { + // C-type + when (head) { + else -> throw UnsupportedOperationException("Unknown Head byte 0x${head.toString(16).padStart(2,'0').toUpperCase()}") + } + } + else -> { + // T-type + when (head) { + else -> throw UnsupportedOperationException("Unknown Head byte 0x${head.toString(16).padStart(2,'0').toUpperCase()}") + } + } + } + } + + private fun Int.unzero(n: Int) = if (this == 0) n else this /** * @param mode 0-Low, 1-High