mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-16 07:56:06 +09:00
more opcodes
This commit is contained in:
@@ -31,21 +31,31 @@ internal class GotoScanline(val line: Int) : DrawCall {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class ChangeGraphicsMode(val mode: Int) : DrawCall {
|
||||||
|
override fun execute(gpu: GraphicsAdapter) {
|
||||||
|
gpu.mmio_write(12L, mode.toByte())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal class JumpIfScanline(
|
internal class JumpIfScanline(
|
||||||
|
val reg: Int,
|
||||||
val compare: Int,
|
val compare: Int,
|
||||||
val whenLessThan: Int,
|
val whenLessThan: Int,
|
||||||
val whenEqualTo: Int,
|
val whenEqualTo: Int,
|
||||||
val whenGreaterThan: Int
|
val whenGreaterThan: Int
|
||||||
) : DrawCall {
|
) : DrawCall {
|
||||||
override fun execute(gpu: GraphicsAdapter) {
|
override fun execute(gpu: GraphicsAdapter) {
|
||||||
if (gpu.rScanline < compare) {
|
// TODO regValue = when ...
|
||||||
if (whenLessThan != 65535) gpu.rScanline = whenLessThan - 1
|
val regValue = gpu.rScanline
|
||||||
|
|
||||||
|
if (regValue < compare) {
|
||||||
|
if (whenLessThan != 65535) gpu.drawCallProgramCounter = whenLessThan - 1
|
||||||
}
|
}
|
||||||
else if (gpu.rScanline == compare) {
|
else if (regValue == compare) {
|
||||||
if (whenEqualTo != 65535) gpu.rScanline = whenEqualTo - 1
|
if (whenEqualTo != 65535) gpu.drawCallProgramCounter = whenEqualTo - 1
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (whenGreaterThan != 65535) gpu.rScanline = whenGreaterThan - 1
|
if (whenGreaterThan != 65535) gpu.drawCallProgramCounter = whenGreaterThan - 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,17 +79,20 @@ internal class DrawCallDrawLines(
|
|||||||
|
|
||||||
|
|
||||||
internal class DrawCallCopyPixels(
|
internal class DrawCallCopyPixels(
|
||||||
val opCount: Int,
|
val useTransparency: Boolean,
|
||||||
val addrFrom: Int,
|
val width: Int,
|
||||||
val xPos: Int,
|
val height: Int,
|
||||||
val lineLength: Int,
|
val transparencyKey: Int,
|
||||||
val stride1: Int,
|
val xpos: Int,
|
||||||
val stride2: Int,
|
val baseAddr: Int,
|
||||||
val stride3: Int,
|
val stride: Int,
|
||||||
val stride4: Int,
|
val colourMath1: Int,
|
||||||
val stride5: Int
|
val colourMath2: Int
|
||||||
) : DrawCall {
|
) : DrawCall {
|
||||||
override fun execute(gpu: GraphicsAdapter) {
|
override fun execute(gpu: GraphicsAdapter) {
|
||||||
TODO("Not yet implemented")
|
if (useTransparency)
|
||||||
|
gpu.blockCopyTransparency(width, height, xpos, gpu.rScanline, transparencyKey.toByte(), baseAddr, stride)
|
||||||
|
else
|
||||||
|
gpu.blockCopy(width, height, xpos, gpu.rScanline, baseAddr, stride)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -430,17 +430,13 @@ open class GraphicsAdapter(private val assetsRoot: String, val vm: VM, val confi
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
in 0x20..0x25 -> {
|
0x60.toByte() -> {
|
||||||
return DrawCallCopyPixels(
|
return JumpIfScanline(
|
||||||
(head and 0xF).toInt() + 1,
|
bytes[1].toUint(),
|
||||||
bytes[1].toUint().shl(16) or bytes[2].toUint().shl(8) or bytes[3].toUint(),
|
toBigInt(bytes[2], bytes[3]),
|
||||||
bytes[4].toUint().shl(8) or bytes[5].toUint(),
|
toBigInt(bytes[4], bytes[5]),
|
||||||
bytes[6].toUint().shl(8) or bytes[7].toUint(),
|
toBigInt(bytes[6], bytes[7]),
|
||||||
bytes[8].toUint().shl(8) or bytes[9].toUint(),
|
toBigInt(bytes[8], bytes[9])
|
||||||
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()}")
|
else -> throw UnsupportedOperationException("Unknown Head byte 0x${head.toString(16).padStart(2,'0').toUpperCase()}")
|
||||||
@@ -448,20 +444,81 @@ open class GraphicsAdapter(private val assetsRoot: String, val vm: VM, val confi
|
|||||||
}
|
}
|
||||||
in -16..-1 -> {
|
in -16..-1 -> {
|
||||||
// C-type
|
// C-type
|
||||||
when (head) {
|
val call1 = bytesToControlCalls(bytes.sliceArray(0..5))
|
||||||
else -> throw UnsupportedOperationException("Unknown Head byte 0x${head.toString(16).padStart(2,'0').toUpperCase()}")
|
val call2 = bytesToControlCalls(bytes.sliceArray(6..11))
|
||||||
}
|
val call3 = bytesToControlCalls(bytes.sliceArray(12..17))
|
||||||
|
return DrawCallCompound(call1, call2, call3)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
// T-type
|
// T-type
|
||||||
when (head) {
|
when (head) {
|
||||||
|
in 0xA0..0xA1 -> {
|
||||||
|
return DrawCallCopyPixels(
|
||||||
|
(head and 2) == 1.toByte(),
|
||||||
|
bytes[1].toUint().unzero(256), bytes[2].toUint().unzero(256),
|
||||||
|
bytes[3].toUint(),
|
||||||
|
toBigInt(bytes[4], bytes[5]),
|
||||||
|
toBigInt(bytes[6], bytes[7], bytes[8]),
|
||||||
|
toBigInt(bytes[9], bytes[10], bytes[11]),
|
||||||
|
toBigInt(bytes[12], bytes[13], bytes[14]),
|
||||||
|
toBigInt(bytes[15], bytes[16], bytes[17])
|
||||||
|
)
|
||||||
|
}
|
||||||
else -> throw UnsupportedOperationException("Unknown Head byte 0x${head.toString(16).padStart(2,'0').toUpperCase()}")
|
else -> throw UnsupportedOperationException("Unknown Head byte 0x${head.toString(16).padStart(2,'0').toUpperCase()}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun bytesToControlCalls(bytes: ByteArray): DrawCall {
|
||||||
|
return when (toBigInt(bytes[0], bytes[1])) {
|
||||||
|
0xF00F -> DrawCallEnd
|
||||||
|
0xF100 -> GotoScanline(toBigInt(bytes[2], bytes[3]))
|
||||||
|
0xF101 -> ChangeGraphicsMode(toBigInt(bytes[2], bytes[3]))
|
||||||
|
0xFFFF -> DrawCallNop
|
||||||
|
else -> throw UnsupportedOperationException("Unknown Opcode 0x${toBigInt(bytes[0], bytes[1]).toString(16).padStart(4, '0').toUpperCase()}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun Int.unzero(n: Int) = if (this == 0) n else this
|
private fun Int.unzero(n: Int) = if (this == 0) n else this
|
||||||
|
private fun toBigInt(byte1: Byte, byte2: Byte, byte3: Byte? = null): Int {
|
||||||
|
if (byte3 != null)
|
||||||
|
return byte1.toUint().shl(16) or byte2.toUint().shl(8) or byte3.toUint()
|
||||||
|
else
|
||||||
|
return byte1.toUint().shl(8) or byte2.toUint()
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun blockCopy(width: Int, height: Int, x: Int, y: Int, baseAddr: Int, stride: Int) {
|
||||||
|
var line = y
|
||||||
|
var srcPtr = vm.usermem.ptr + baseAddr
|
||||||
|
while (line < y + height) {
|
||||||
|
val destPtr = framebuffer.ptr + line * WIDTH + x
|
||||||
|
|
||||||
|
UnsafeHelper.memcpy(srcPtr, destPtr, width.toLong())
|
||||||
|
|
||||||
|
srcPtr += stride
|
||||||
|
line += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun blockCopyTransparency(width: Int, height: Int, x: Int, y: Int, transparencyKey: Byte, baseAddr: Int, stride: Int) {
|
||||||
|
var line = y
|
||||||
|
var srcPtr = baseAddr * 1L
|
||||||
|
while (line < y + height) {
|
||||||
|
val destPtr = line * WIDTH + x * 1L
|
||||||
|
|
||||||
|
// UnsafeHelper.memcpy(srcPtr, destPtr, width.toLong())
|
||||||
|
for (col in x until x + width) {
|
||||||
|
val pixel = vm.usermem[srcPtr + col]
|
||||||
|
if (pixel != transparencyKey) {
|
||||||
|
framebuffer[destPtr + col] = pixel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
srcPtr += stride
|
||||||
|
line += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mode 0-Low, 1-High
|
* @param mode 0-Low, 1-High
|
||||||
|
|||||||
Reference in New Issue
Block a user