faster partial reading of file wip

This commit is contained in:
minjaesong
2022-04-13 17:30:42 +09:00
parent 95bfaae1da
commit 95b0d4672e
3 changed files with 96 additions and 8 deletions

View File

@@ -1,54 +1,106 @@
let filename = exec_args[1]
const FBUF_SIZE = 560*448
const MAGIC = [0x1F, 0x54, 0x53, 0x56, 0x4D, 0x4D, 0x4F, 0x56]
let status = filesystem.open("A", filename, "R")
if (status) return status
println("Reading...")
let bytes = filesystem.readAllBytes("A")
//let bytes = filesystem.readAllBytes("A")
con.clear()
let readCount = 0
function readBytes(length) {
let ret = new Int8Array(length)
/*let ret = new Int8Array(length)
for (let k = 0; k < length; k++) {
ret[k] = bytes[readCount]
readCount += 1
}
return ret
return ret*/
let ptr = sys.malloc(length)
let requiredBlocks = (readCount == 0) + Math.floor((readCount + length) / 4096) - Math.floor(readCount / 4096)
let port = filesystem._toPorts("A")
let completedReads = 0
for (let bc = 0; bc < requiredBlocks; bc++) {
if (readCount % 4096 == 0) {
com.sendMessage(port[0], "READ")
let thisBlockLen = com.fetchResponse(port[0]) // [0, 4095]
let remaining = Math.min(4096, length - completedReads)
// copy from read buffer to designated position
sys.memcpy(-4097, ptr + readCount, remaining)
// increment readCount properly
readCount += remaining
completedReads += remaining
}
else {
let padding = 4096 - (readCount % 4096)
let remaining = Math.min(padding, length - completedReads)
// copy from read buffer to designated position
sys.memcpy(-4097 - padding, ptr + readCount, remaining)
// increment readCount properly
readCount += remaining
completedReads += remaining
}
}
return ptr
}
function readInt() {
let b = readBytes(4)
return (b[0] & 255) | ((b[1] & 255) << 8) | ((b[2] & 255) << 16) | ((b[3] & 255) << 24)
let i = (sys.peek(b) & 255) | ((sys.peek(b+1) & 255) << 8) | ((sys.peek(b+2) & 255) << 16) | ((sys.peek(b+3) & 255) << 24)
sys.free(b)
return i
}
function readShort() {
let b = readBytes(2)
return (b[0] & 255) | ((b[1] & 255) << 8)
let i = (sys.peek(b) & 255) | ((sys.peek(b+1) & 255) << 8)
sys.free(b)
return i
}
let magic = readBytes(8)
if (String.fromCharCode.apply(null, magic) != '\x1fTSVMMOV') return 1
// check if magic number matches
MAGIC.forEach((b,i) => {
if (sys.peek(magic + i) & 255 != b) return 1
})
sys.free(magic)
let width = readShort()
let height = readShort()
let fps = readShort()
let frameCount = readInt() % 16777216
serial.println(`Dim: (${width}x${height}), FPS: ${fps}, Frames: ${frameCount}`)
let fbuf = sys.malloc(FBUF_SIZE)
for (let f = 0; f < frameCount; f++) {
serial.println(`Frame #${f+1}`)
let payloadLen = readInt()
let gzipped = readBytes(payloadLen)
gzip.decompTo(gzipped, fbuf)
let gzippedPtr = readBytes(payloadLen)
gzip.decompFromTo(gzippedPtr, payloadLen, fbuf) // should return FBUF_SIZE
dma.ramToFrame(fbuf, 0, FBUF_SIZE)
sys.free(gzippedPtr)
}
sys.free(fbuf)

View File

@@ -11,6 +11,9 @@ class CompressorDelegate(val vm: VM) {
fun comp(str: String) = Companion.comp(str)
fun comp(ba: ByteArray) = Companion.comp(ba)
/**
* @return length of the bytes compressed
*/
fun compFromTo(input: Int, len: Int, output: Int): Int {
val inbytes = ByteArray(len) { vm.peek(input.toLong() + it)!! }
comp(inbytes).let {
@@ -48,6 +51,19 @@ class CompressorDelegate(val vm: VM) {
}
}
/**
* @return length of the bytes compressed
*/
fun decompFromTo(input: Int, len: Int, output: Int): Int {
val inbytes = ByteArray(len) { vm.peek(input.toLong() + it)!! }
decomp(inbytes).let {
it.forEachIndexed { index, byte ->
vm.poke(output.toLong() + index, byte)
}
return it.size
}
}
companion object {
val GZIP_HEADER = byteArrayOf(31, -117, 8) // .gz in DEFLATE

View File

@@ -3,7 +3,9 @@ package net.torvald.tsvm
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import net.torvald.UnsafeHelper
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.toUlong
import net.torvald.tsvm.peripheral.IOSpace
import java.nio.charset.Charset
/**
@@ -16,6 +18,24 @@ class VMJSR223Delegate(val vm: VM) {
fun nanoTime() = System.nanoTime()
fun malloc(size: Int) = vm.malloc(size)
fun free(ptr: Int) = vm.free(ptr)
fun memcpy(from: Int, to: Int, len: Int) {
val len = len.toLong()
// some special cases for native memcpy
val ioSpace = vm.peripheralTable[0].peripheral!! as IOSpace
// within scratchpad memory?
if (from in 0 until 8388608 && (to + len) in 0 until 8388608)
UnsafeHelper.memcpy(vm.usermem.ptr + from, vm.usermem.ptr + to, len)
// first serial read buffer -> usermem
else if (from in -4097 downTo -8192 && (to + len) in 0 until 8388608)
UnsafeHelper.memcpy(ioSpace.blockTransferRx[0].ptr + (-4097 - from), vm.usermem.ptr + to, len)
// usermem -> first serial write buffer
else if (from in 0 until 8388608 && (to + len) in -4097L downTo -8192L)
UnsafeHelper.memcpy(vm.usermem.ptr + from, ioSpace.blockTransferTx[0].ptr + (-4097 - to), len)
else
for (i in 0 until len) {
vm.poke(to + i, vm.peek(from + i)!!)
}
}
fun mapRom(slot: Int) {
vm.romMapping = slot.and(255)
}