mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-08 04:01:51 +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(
|
||||
val reg: Int,
|
||||
val compare: Int,
|
||||
val whenLessThan: Int,
|
||||
val whenEqualTo: Int,
|
||||
val whenGreaterThan: Int
|
||||
) : DrawCall {
|
||||
override fun execute(gpu: GraphicsAdapter) {
|
||||
if (gpu.rScanline < compare) {
|
||||
if (whenLessThan != 65535) gpu.rScanline = whenLessThan - 1
|
||||
// TODO regValue = when ...
|
||||
val regValue = gpu.rScanline
|
||||
|
||||
if (regValue < compare) {
|
||||
if (whenLessThan != 65535) gpu.drawCallProgramCounter = whenLessThan - 1
|
||||
}
|
||||
else if (gpu.rScanline == compare) {
|
||||
if (whenEqualTo != 65535) gpu.rScanline = whenEqualTo - 1
|
||||
else if (regValue == compare) {
|
||||
if (whenEqualTo != 65535) gpu.drawCallProgramCounter = whenEqualTo - 1
|
||||
}
|
||||
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(
|
||||
val opCount: Int,
|
||||
val addrFrom: Int,
|
||||
val xPos: Int,
|
||||
val lineLength: Int,
|
||||
val stride1: Int,
|
||||
val stride2: Int,
|
||||
val stride3: Int,
|
||||
val stride4: Int,
|
||||
val stride5: Int
|
||||
val useTransparency: Boolean,
|
||||
val width: Int,
|
||||
val height: Int,
|
||||
val transparencyKey: Int,
|
||||
val xpos: Int,
|
||||
val baseAddr: Int,
|
||||
val stride: Int,
|
||||
val colourMath1: Int,
|
||||
val colourMath2: Int
|
||||
) : DrawCall {
|
||||
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 -> {
|
||||
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()
|
||||
0x60.toByte() -> {
|
||||
return JumpIfScanline(
|
||||
bytes[1].toUint(),
|
||||
toBigInt(bytes[2], bytes[3]),
|
||||
toBigInt(bytes[4], bytes[5]),
|
||||
toBigInt(bytes[6], bytes[7]),
|
||||
toBigInt(bytes[8], bytes[9])
|
||||
)
|
||||
}
|
||||
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 -> {
|
||||
// C-type
|
||||
when (head) {
|
||||
else -> throw UnsupportedOperationException("Unknown Head byte 0x${head.toString(16).padStart(2,'0').toUpperCase()}")
|
||||
}
|
||||
val call1 = bytesToControlCalls(bytes.sliceArray(0..5))
|
||||
val call2 = bytesToControlCalls(bytes.sliceArray(6..11))
|
||||
val call3 = bytesToControlCalls(bytes.sliceArray(12..17))
|
||||
return DrawCallCompound(call1, call2, call3)
|
||||
}
|
||||
else -> {
|
||||
// T-type
|
||||
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()}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 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
|
||||
|
||||
Reference in New Issue
Block a user