diff --git a/assets/disk0/tvdos/TVDOS.SYS b/assets/disk0/tvdos/TVDOS.SYS index bf223f4..b6c9f15 100644 --- a/assets/disk0/tvdos/TVDOS.SYS +++ b/assets/disk0/tvdos/TVDOS.SYS @@ -1060,20 +1060,6 @@ print = function(str) { Object.freeze(unicode); /////////////////////////////////////////////////////////////////////////////// - -// install other stuffs -var require = (absdir) => { - let moduleFile = files.open(absdir) - if (!moduleFile.exists) throw Error("No such file: " + absdir) - let moduleScript = moduleFile.sread() - return eval(`let exports = {}; ${moduleScript}; Object.freeze(exports)`) -} - - -var GL = require("A:/tvdos/include/gl.js") - - - let checkTerm = `if (sys.peek(-49)&1) throw new InterruptedException();` let injectIntChk = (s, n) => { // primitive way of injecting a code; will replace a JS string that matches the regex... @@ -1085,6 +1071,21 @@ let injectIntChk = (s, n) => { return k; } + + +// install other stuffs +var require = (absdir) => { + let moduleFile = files.open(absdir) + if (!moduleFile.exists) throw Error("No such file: " + absdir) + let moduleScript = moduleFile.sread() + var intchkFunName = `tvdosSIGTERM_${generateRandomHashStr(16)}`; + return eval(`var ${intchkFunName} = function(){ ${checkTerm} };let exports = {}; ${injectIntChk(moduleScript, intchkFunName)}; Object.freeze(exports)`) +} + + +var GL = require("A:/tvdos/include/gl.js") + + // @param cmdsrc JS source code // @param args arguments for the program, must be Array, and args[0] is always the name of the program, e.g. // for command line 'echo foo bar', args[0] must be 'echo' diff --git a/assets/disk0/tvdos/bin/encodemov.js b/assets/disk0/tvdos/bin/encodemov.js index 5ab96b7..d36bb68 100644 --- a/assets/disk0/tvdos/bin/encodemov.js +++ b/assets/disk0/tvdos/bin/encodemov.js @@ -1,12 +1,12 @@ // some manual configurations // let IPFMODE = 2 // 1 or 2 -let TOTAL_FRAMES = 800 -let FPS = 24 +let TOTAL_FRAMES = 3813 +let FPS = 30 let WIDTH = 560 let HEIGHT = 448 -let PATHFUN = (i) => `/welkom/${(''+i).padStart(4,'0')}.png` // how can be the image file found, if a frame number (starts from 1) were given -let AUDIOTRACK = 'welkom/welkom.pcm' +let PATHFUN = (i) => `/ddol2/${(''+i).padStart(5,'0')}.bmp` // how can be the image file found, if a frame number (starts from 1) were given +let AUDIOTRACK = 'ddol.pcm' // to export video to its frames: // ffmpeg -i file.mp4 file/%05d.bmp // the input frames must be resized (and cropped) beforehand, using ImageMagick is recommended, like so: diff --git a/assets/disk0/tvdos/bin/playmov.js b/assets/disk0/tvdos/bin/playmov.js index b99db81..d335478 100644 --- a/assets/disk0/tvdos/bin/playmov.js +++ b/assets/disk0/tvdos/bin/playmov.js @@ -1,116 +1,20 @@ const FBUF_SIZE = 560*448 const MAGIC = [0x1F, 0x54, 0x53, 0x56, 0x4D, 0x4D, 0x4F, 0x56] -const port = _TVDOS.DRV.FS.SERIAL._toPorts("A")[0] const fullFilePath = _G.shell.resolvePathInput(exec_args[1]) const FILE_LENGTH = files.open(fullFilePath.full).size -serial.println(`Reading ${FILE_LENGTH} bytes...`) - -com.sendMessage(port, "DEVRST\x17") -com.sendMessage(port, `OPENR"${fullFilePath.string}",1`) -let statusCode = com.getStatusCode(port) - -if (statusCode != 0) { - printerrln(`No such file (${statusCode})`) - return statusCode -} - -com.sendMessage(port, "READ") -statusCode = com.getStatusCode(port) -if (statusCode != 0) { - printerrln("READ failed with "+statusCode) - return statusCode -} - -con.clear(); con.curs_set(0) - -let readCount = 0 - -function readBytes(length, ptrToDecode) { - let ptr = (ptrToDecode === undefined) ? sys.malloc(length) : ptrToDecode - let requiredBlocks = Math.floor((readCount + length) / 4096) - Math.floor(readCount / 4096) - - let completedReads = 0 - - //serial.println(`readBytes(${length}); readCount = ${readCount}`) - - for (let bc = 0; bc < requiredBlocks + 1; bc++) { - if (completedReads >= length) break - - if (readCount % 4096 == 0) { - //serial.println("READ from serial") - // pull the actual message - sys.poke(-4093 - port, 6);sys.sleep(0) // spinning is required as Graal run is desynced with the Java side - - let blockTransferStatus = ((sys.peek(-4085 - port*2) & 255) | ((sys.peek(-4086 - port*2) & 255) << 8)) - let thisBlockLen = blockTransferStatus & 4095 - if (thisBlockLen == 0) thisBlockLen = 4096 // [1, 4096] - let hasMore = (blockTransferStatus & 0x8000 != 0) +con.clear();con.curs_set(0) - //serial.println(`block: (${thisBlockLen})[${[...Array(thisBlockLen).keys()].map(k => (sys.peek(-4097 - k) & 255).toString(16).padStart(2,'0')).join()}]`) - - let remaining = Math.min(thisBlockLen, length - completedReads) - - //serial.println(`Pulled a block (${thisBlockLen}); readCount = ${readCount}, completedReads = ${completedReads}, remaining = ${remaining}`) - - // copy from read buffer to designated position - sys.memcpy(-4097, ptr + completedReads, remaining) - - // increment readCount properly - readCount += remaining - completedReads += remaining - } - else { - let padding = readCount % 4096 - let remaining = length - completedReads - let thisBlockLen = Math.min(4096 - padding, length - completedReads) - - //serial.println(`padding = ${padding}; remaining = ${remaining}`) - - //serial.println(`block: (${thisBlockLen})[${[...Array(thisBlockLen).keys()].map(k => (sys.peek(-4097 - padding - k) & 255).toString(16).padStart(2,'0')).join()}]`) - - //serial.println(`Reusing a block (${thisBlockLen}); readCount = ${readCount}, completedReads = ${completedReads}`) - - // copy from read buffer to designated position - sys.memcpy(-4097 - padding, ptr + completedReads, thisBlockLen) - - // increment readCount properly - readCount += thisBlockLen - completedReads += thisBlockLen - } - } - - //serial.println(`END readBytes(${length}); readCount = ${readCount}\n`) - - return ptr -} - -function readInt() { - let b = readBytes(4) - let i = (sys.peek(b) & 255) | ((sys.peek(b+1) & 255) << 8) | ((sys.peek(b+2) & 255) << 16) | ((sys.peek(b+3) & 255) << 24) - - //serial.println(`readInt(); bytes: ${sys.peek(b)}, ${sys.peek(b+1)}, ${sys.peek(b+2)}, ${sys.peek(b+3)} = ${i}\n`) - - sys.free(b) - return i -} - -function readShort() { - let b = readBytes(2) - let i = (sys.peek(b) & 255) | ((sys.peek(b+1) & 255) << 8) - - //serial.println(`readShort(); bytes: ${sys.peek(b)}, ${sys.peek(b+1)} = ${i}\n`) - - sys.free(b) - return i -} +let seqread = require("seqread") +seqread.prepare(fullFilePath.full) -let magic = readBytes(8) + +let magic = seqread.readBytes(8) let magicMatching = true // check if magic number matches @@ -127,19 +31,19 @@ if (!magicMatching) { } -let width = readShort() -let height = readShort() -let fps = readShort(); if (fps == 0) fps = 9999 +let width = seqread.readShort() +let height = seqread.readShort() +let fps = seqread.readShort(); if (fps == 0) fps = 9999 //fps = 9999 let frameTime = 1.0 / fps -let frameCount = readInt() % 16777216 -let globalType = readShort() -sys.free(readBytes(12)) // skip 12 bytes +let frameCount = seqread.readInt() % 16777216 +let globalType = seqread.readShort() +sys.free(seqread.readBytes(12)) // skip 12 bytes let akku = frameTime let framesRendered = 0 -//serial.println(readCount) // must say 18 +//serial.println(seqread.getReadCount()) // must say 18 //serial.println(`Dim: (${width}x${height}), FPS: ${fps}, Frames: ${frameCount}`) /*if (type != 4 && type != 5 && type != 260 && type != 261) { @@ -165,7 +69,7 @@ audio.setPcmMode(0) audio.setMasterVolume(0, 255) renderLoop: -while (readCount < FILE_LENGTH) { +while (seqread.getReadCount() < FILE_LENGTH) { let t1 = sys.nanoTime() if (akku >= frameTime) { @@ -178,9 +82,9 @@ while (readCount < FILE_LENGTH) { if (frameUnit != 0) { // skip frames if necessary - while (frameUnit >= 1 && readCount < FILE_LENGTH) { + while (frameUnit >= 1 && seqread.getReadCount() < FILE_LENGTH) { - let packetType = readShort() + let packetType = seqread.readShort() // ideally, first two packets will be audio packets @@ -190,7 +94,7 @@ while (readCount < FILE_LENGTH) { } // background colour packets else if (65279 == packetType) { - let rgbx = readInt() + let rgbx = seqread.readInt() graphics.setBackground( (rgbx & 0xFF000000) >>> 24, (rgbx & 0x00FF0000) >>> 16, @@ -202,14 +106,14 @@ while (readCount < FILE_LENGTH) { // iPF if (packetType == 4 || packetType == 5 || packetType == 260 || packetType == 261) { let decodefun = (packetType > 255) ? graphics.decodeIpf2 : graphics.decodeIpf1 - let payloadLen = readInt() + let payloadLen = seqread.readInt() if (framesRead >= frameCount) { break renderLoop } framesRead += 1 - let gzippedPtr = readBytes(payloadLen) + let gzippedPtr = seqread.readBytes(payloadLen) framesRendered += 1 if (frameUnit == 1) { @@ -226,14 +130,16 @@ while (readCount < FILE_LENGTH) { sys.free(gzippedPtr) } else { - throw Error(`Unknown Video Packet with type ${packetType} at offset ${readCount - 2}`) + throw Error(`Unknown Video Packet with type ${packetType} at offset ${seqread.getReadCount() - 2}`) } } // audio packets else if (4096 <= packetType && packetType <= 6133) { if (4097 == packetType) { - let readLength = readInt() - let samples = readBytes(readLength) + let readLength = seqread.readInt() + let samples = seqread.readBytes(readLength) + + if (readLength == 0) throw Error("Readlength is zero") audio.putPcmDataByPtr(samples, readLength, 0) audio.setSampleUploadLength(0, readLength) @@ -242,11 +148,11 @@ while (readCount < FILE_LENGTH) { sys.free(samples) } else { - throw Error(`Audio Packet with type ${packetType} at offset ${readCount - 2}`) + throw Error(`Audio Packet with type ${packetType} at offset ${seqread.getReadCount() - 2}`) } } else { - println(`Unknown Packet with type ${packetType} at offset ${readCount - 2}`) + println(`Unknown Packet with type ${packetType} at offset ${seqread.getReadCount() - 2}`) } } } diff --git a/assets/disk0/tvdos/bin/playwav.js b/assets/disk0/tvdos/bin/playwav.js index 47465c7..f08c120 100644 --- a/assets/disk0/tvdos/bin/playwav.js +++ b/assets/disk0/tvdos/bin/playwav.js @@ -1,128 +1,12 @@ // this program will serve as a step towards the ADPCM decoding, and tests if RIFF data are successfully decoded. let HW_SAMPLING_RATE = 30000 -let filename = exec_args[1] -const port = _TVDOS.DRV.FS.SERIAL._toPorts("A")[0] +let filename = _G.shell.resolvePathInput(exec_args[1]).full function printdbg(s) { if (0) serial.println(s) } function printvis(s) { if (0) println(s) } -//println("Reading...") -//serial.println("!!! READING") +let seqread = require("seqread") -com.sendMessage(port, "DEVRST\x17") -com.sendMessage(port, `OPENR"${filename}",1`) -let statusCode = com.getStatusCode(port) - -if (statusCode != 0) { - printerrln(`No such file (${statusCode})`) - return statusCode -} - -com.sendMessage(port, "READ") -statusCode = com.getStatusCode(port) -if (statusCode != 0) { - printerrln("READ failed with "+statusCode) - return statusCode -} - - - - -let readCount = 0 -function readBytes(length, ptrToDecode) { - if (length <= 0) return - let ptr = (ptrToDecode === undefined) ? sys.malloc(length) : ptrToDecode - let requiredBlocks = Math.floor((readCount + length) / 4096) - Math.floor(readCount / 4096) - - let completedReads = 0 - -// serial.println(`readBytes(${length}); readCount = ${readCount}`) - - for (let bc = 0; bc < requiredBlocks + 1; bc++) { - if (completedReads >= length) break - - if (readCount % 4096 == 0) { -// serial.println("READ from serial") - // pull the actual message - sys.poke(-4093 - port, 6);sys.sleep(0) // spinning is required as Graal run is desynced with the Java side - - let blockTransferStatus = ((sys.peek(-4085 - port*2) & 255) | ((sys.peek(-4086 - port*2) & 255) << 8)) - let thisBlockLen = blockTransferStatus & 4095 - if (thisBlockLen == 0) thisBlockLen = 4096 // [1, 4096] - let hasMore = (blockTransferStatus & 0x8000 != 0) - - -// serial.println(`block: (${thisBlockLen})[${[...Array(thisBlockLen).keys()].map(k => (sys.peek(-4097 - k) & 255).toString(16).padStart(2,'0')).join()}]`) - - let remaining = Math.min(thisBlockLen, length - completedReads) - -// serial.println(`Pulled a block (${thisBlockLen}); readCount = ${readCount}, completedReads = ${completedReads}, remaining = ${remaining}`) - - // copy from read buffer to designated position - sys.memcpy(-4097, ptr + completedReads, remaining) - - // increment readCount properly - readCount += remaining - completedReads += remaining - } - else { - let padding = readCount % 4096 - let remaining = length - completedReads - let thisBlockLen = Math.min(4096 - padding, length - completedReads) - -// serial.println(`padding = ${padding}; remaining = ${remaining}`) -// serial.println(`block: (${thisBlockLen})[${[...Array(thisBlockLen).keys()].map(k => (sys.peek(-4097 - padding - k) & 255).toString(16).padStart(2,'0')).join()}]`) -// serial.println(`Reusing a block (${thisBlockLen}); readCount = ${readCount}, completedReads = ${completedReads}`) - - // copy from read buffer to designated position - sys.memcpy(-4097 - padding, ptr + completedReads, thisBlockLen) - - // increment readCount properly - readCount += thisBlockLen - completedReads += thisBlockLen - } - } - - //serial.println(`END readBytes(${length}); readCount = ${readCount}\n`) - - return ptr -} - -function readInt() { - let b = readBytes(4) - let i = (sys.peek(b)) | (sys.peek(b+1) << 8) | (sys.peek(b+2) << 16) | (sys.peek(b+3) << 24) - sys.free(b) - return i -} - -function readShort() { - let b = readBytes(2) - let i = (sys.peek(b)) | (sys.peek(b+1) << 8) - sys.free(b) - return i -} - -function readFourCC() { - let b = readBytes(4) - let s = String.fromCharCode(sys.peek(b), sys.peek(b+1), sys.peek(b+2), sys.peek(b+3)) - sys.free(b) - return s -} - -function readString(length) { - let b = readBytes(length) - let s = "" - for (let k = 0; k < length; k++) { - s += String.fromCharCode(sys.peek(b + k)) - } - sys.free(b) - return s -} - -function discardBytes(n) { - let b = readBytes(n) - if (b !== undefined) sys.free(b) -} @@ -156,14 +40,23 @@ function lerpAndRound(start, end, x) { } + +//println("Reading...") +//serial.println("!!! READING") + +seqread.prepare(filename) + + + + // decode header -if (readFourCC() != "RIFF") { +if (seqread.readFourCC() != "RIFF") { throw Error("File not RIFF") } -const FILE_SIZE = readInt() // size from "WAVEfmt" +const FILE_SIZE = seqread.readInt() // size from "WAVEfmt" -if (readFourCC() != "WAVE") { +if (seqread.readFourCC() != "WAVE") { throw Error("File is RIFF but not WAVE") } @@ -444,20 +337,20 @@ function decodeInfilePcm(inPtr, outPtr, inputLen) { throw Error(`PCM Type not LPCM or ADPCM (${pcmType})`) } // read chunks loop -while (readCount < FILE_SIZE - 8) { - let chunkName = readFourCC() - let chunkSize = readInt() - printdbg(`Reading '${chunkName}' at ${readCount - 8}`) +while (seqread.getReadCount() < FILE_SIZE - 8) { + let chunkName = seqread.readFourCC() + let chunkSize = seqread.readInt() + printdbg(`Reading '${chunkName}' at ${seqread.getReadCount() - 8}`) // here be lotsa if-else if ("fmt " == chunkName) { - pcmType = readShort() - nChannels = readShort() - samplingRate = readInt() - discardBytes(4) - blockSize = readShort() - bitsPerSample = readShort() - discardBytes(chunkSize - 16) + pcmType = seqread.readShort() + nChannels = seqread.readShort() + samplingRate = seqread.readInt() + seqread.skip(4) + blockSize = seqread.readShort() + bitsPerSample = seqread.readShort() + seqread.skip(chunkSize - 16) // define BLOCK_SIZE as integer multiple of blockSize, for LPCM // ADPCM will be decoded per-block basis @@ -479,24 +372,24 @@ while (readCount < FILE_SIZE - 8) { printdbg(`BLOCK_SIZE=${BLOCK_SIZE}, INFILE_BLOCK_SIZE=${INFILE_BLOCK_SIZE}`) } else if ("LIST" == chunkName) { - let startOffset = readCount - let subChunkName = readFourCC() - while (readCount < startOffset + chunkSize) { + let startOffset = seqread.getReadCount() + let subChunkName = seqread.readFourCC() + while (seqread.getReadCount() < startOffset + chunkSize) { printdbg(`${chunkName} ${subChunkName}`) if ("INFO" == subChunkName) { - let key = readFourCC() - let valueLen = readInt() - let value = readString(valueLen) + let key = seqread.readFourCC() + let valueLen = seqread.readInt() + let value = seqread.readString(valueLen) comments[key] = value } else { - discardBytes(startOffset + chunkSize - readCount) + seqread.skip(startOffset + chunkSize - seqread.getReadCount()) } } printComments() } else if ("data" == chunkName) { - let startOffset = readCount + let startOffset = seqread.getReadCount() printdbg(`WAVE size: ${chunkSize}, startOffset=${startOffset}`) // check if the format is actually playable @@ -516,12 +409,12 @@ while (readCount < FILE_SIZE - 8) { audio.setMasterVolume(0, 255) let readLength = 1 - while (readCount < startOffset + chunkSize && readLength > 0) { + while (seqread.getReadCount() < startOffset + chunkSize && readLength > 0) { let queueSize = audio.getPosition(0) if (queueSize <= 1) { // upload four samples for lag-safely for (let repeat = QUEUE_MAX - queueSize; repeat > 0; repeat--) { - let remainingBytes = FILE_SIZE - 8 - readCount + let remainingBytes = FILE_SIZE - 8 - seqread.getReadCount() readLength = (remainingBytes < INFILE_BLOCK_SIZE) ? remainingBytes : INFILE_BLOCK_SIZE if (readLength <= 0) { @@ -529,9 +422,9 @@ while (readCount < FILE_SIZE - 8) { break } - printdbg(`offset: ${readCount}/${FILE_SIZE + 8}; readLength: ${readLength}`) + printdbg(`offset: ${seqread.getReadCount()}/${FILE_SIZE + 8}; readLength: ${readLength}`) - readBytes(readLength, readPtr) + seqread.readBytes(readLength, readPtr) let decodedSampleLength = decodeInfilePcm(readPtr, decodePtr, readLength) printdbg(` decodedSampleLength: ${decodedSampleLength}`) @@ -546,23 +439,23 @@ while (readCount < FILE_SIZE - 8) { audio.play(0) } - let remainingBytes = FILE_SIZE - 8 - readCount - printdbg(`readLength = ${readLength}; remainingBytes2 = ${remainingBytes}; readCount = ${readCount}; startOffset + chunkSize = ${startOffset + chunkSize}`) + let remainingBytes = FILE_SIZE - 8 - seqread.getReadCount() + printdbg(`readLength = ${readLength}; remainingBytes2 = ${remainingBytes}; seqread.getReadCount() = ${seqread.getReadCount()}; startOffset + chunkSize = ${startOffset + chunkSize}`) sys.spin() sys.sleep(10) } } else { - discardBytes(chunkSize) + seqread.skip(chunkSize) } - let remainingBytes = FILE_SIZE - 8 - readCount + let remainingBytes = FILE_SIZE - 8 - seqread.getReadCount() printdbg(`remainingBytes2 = ${remainingBytes}`) sys.spin() } audio.stop(0) if (readPtr !== undefined) sys.free(readPtr) -if (decodePtr !== undefined) sys.free(decodePtr) \ No newline at end of file +if (decodePtr !== undefined) sys.free(decodePtr) diff --git a/assets/disk0/tvdos/include/example.js b/assets/disk0/tvdos/include/example.js index e9d681d..0c87362 100644 --- a/assets/disk0/tvdos/include/example.js +++ b/assets/disk0/tvdos/include/example.js @@ -1,4 +1,6 @@ -exports.greet = function() { println("Hello, module!") } +var testfun = function() { println("peekaboo!") } + +exports = {greet} /* diff --git a/assets/disk0/tvdos/include/seqread.js b/assets/disk0/tvdos/include/seqread.js new file mode 100644 index 0000000..d6287ba --- /dev/null +++ b/assets/disk0/tvdos/include/seqread.js @@ -0,0 +1,137 @@ + +let readCount = 0 +let port = undefined + +function prepare(fullPath) { + if (fullPath[2] != '/' && fullPath[2] != '\\') throw Error("Expected full path with drive letter, got " + fullPath) + + + readCount = 0 + + let driveLetter = fullPath[0].toUpperCase() + let diskPath = fullPath.substring(2).replaceAll("\\",'/') + + // remove '/' at the head of the diskPath + while (diskPath[0] == '/') { + diskPath = diskPath.substring(1) + } + + port = _TVDOS.DRV.FS.SERIAL._toPorts(driveLetter)[0] + + com.sendMessage(port, "DEVRST\x17") + com.sendMessage(port, `OPENR"${diskPath}",1`) + let statusCode = com.getStatusCode(port) + + if (statusCode != 0) { + throw Error(`No such file (${statusCode}; ${driveLetter}:\\${diskPath})`) + return statusCode + } + + com.sendMessage(port, "READ") + statusCode = com.getStatusCode(port) + if (statusCode != 0) { + throw Error("READ failed with "+statusCode) + return statusCode + } +} + +function readBytes(length, ptrToDecode) { + if (length <= 0) return + let ptr = (ptrToDecode === undefined) ? sys.malloc(length) : ptrToDecode + let requiredBlocks = Math.floor((readCount + length) / 4096) - Math.floor(readCount / 4096) + + let completedReads = 0 + +// serial.println(`readBytes(${length}); readCount = ${readCount}`) + + for (let bc = 0; bc < requiredBlocks + 1; bc++) { + if (completedReads >= length) break + + if (readCount % 4096 == 0) { +// serial.println("READ from serial") + // pull the actual message + sys.poke(-4093 - port, 6);sys.sleep(0) // spinning is required as Graal run is desynced with the Java side + + let blockTransferStatus = ((sys.peek(-4085 - port*2) & 255) | ((sys.peek(-4086 - port*2) & 255) << 8)) + let thisBlockLen = blockTransferStatus & 4095 + if (thisBlockLen == 0) thisBlockLen = 4096 // [1, 4096] + let hasMore = (blockTransferStatus & 0x8000 != 0) + + +// serial.println(`block: (${thisBlockLen})[${[...Array(thisBlockLen).keys()].map(k => (sys.peek(-4097 - k) & 255).toString(16).padStart(2,'0')).join()}]`) + + let remaining = Math.min(thisBlockLen, length - completedReads) + +// serial.println(`Pulled a block (${thisBlockLen}); readCount = ${readCount}, completedReads = ${completedReads}, remaining = ${remaining}`) + + // copy from read buffer to designated position + sys.memcpy(-4097, ptr + completedReads, remaining) + + // increment readCount properly + readCount += remaining + completedReads += remaining + } + else { + let padding = readCount % 4096 + let remaining = length - completedReads + let thisBlockLen = Math.min(4096 - padding, length - completedReads) + +// serial.println(`padding = ${padding}; remaining = ${remaining}`) +// serial.println(`block: (${thisBlockLen})[${[...Array(thisBlockLen).keys()].map(k => (sys.peek(-4097 - padding - k) & 255).toString(16).padStart(2,'0')).join()}]`) +// serial.println(`Reusing a block (${thisBlockLen}); readCount = ${readCount}, completedReads = ${completedReads}`) + + // copy from read buffer to designated position + sys.memcpy(-4097 - padding, ptr + completedReads, thisBlockLen) + + // increment readCount properly + readCount += thisBlockLen + completedReads += thisBlockLen + } + } + + //serial.println(`END readBytes(${length}); readCount = ${readCount}\n`) + + return ptr +} + +function readInt() { + let b = readBytes(4) + let i = (sys.peek(b)) | (sys.peek(b+1) << 8) | (sys.peek(b+2) << 16) | (sys.peek(b+3) << 24) + sys.free(b) + return i +} + +function readShort() { + let b = readBytes(2) + let i = (sys.peek(b)) | (sys.peek(b+1) << 8) + sys.free(b) + return i +} + +function readFourCC() { + let b = readBytes(4) + let s = String.fromCharCode(sys.peek(b), sys.peek(b+1), sys.peek(b+2), sys.peek(b+3)) + sys.free(b) + return s +} + +function readString(length) { + let b = readBytes(length) + let s = "" + for (let k = 0; k < length; k++) { + s += String.fromCharCode(sys.peek(b + k)) + } + sys.free(b) + return s +} + +function skip(n) { + let b = readBytes(n) + if (b !== undefined) sys.free(b) +} + +function getReadCount() { + return readCount +} + +exports = {prepare, readBytes, readInt, readShort, readFourCC, readString, skip, getReadCount} \ No newline at end of file diff --git a/tsvm_core/src/net/torvald/tsvm/peripheral/AudioAdapter.kt b/tsvm_core/src/net/torvald/tsvm/peripheral/AudioAdapter.kt index 3435d3a..7569117 100644 --- a/tsvm_core/src/net/torvald/tsvm/peripheral/AudioAdapter.kt +++ b/tsvm_core/src/net/torvald/tsvm/peripheral/AudioAdapter.kt @@ -38,11 +38,15 @@ private class RenderRunnable(val playhead: AudioAdapter.Playhead) : Runnable { // printdbg("P${playhead.index+1} go back to spinning") - Thread.sleep(2) + Thread.sleep(12) } else if (playhead.isPlaying && writeQueue.isEmpty) { printdbg("Queue exhausted, stopping audio device...") - playhead.audioDevice.stop() + + // TODO: wait for 1-2 seconds then finally stop the device +// playhead.audioDevice.stop() + + Thread.sleep(12) } } @@ -77,6 +81,10 @@ private class WriteQueueingRunnable(val playhead: AudioAdapter.Playhead, val pcm it.position += 1 Thread.sleep(6) } + else if (it.pcmUpload) { + printdbg("Rejecting samples (queueSize: ${it.pcmQueue.size}, uploadLength: ${it.pcmUploadLength})") + Thread.sleep(6) + } } Thread.sleep(1) @@ -394,7 +402,7 @@ class AudioAdapter(val vm: VM) : PeriBase { } } - fun getPcmQueueCapacity() = QUEUE_SIZE[pcmQueueSizeIndex] + fun getPcmQueueCapacity() = 2147483647//QUEUE_SIZE[pcmQueueSizeIndex] fun dispose() { println("AudioDevice dispose ${parent.renderThreads[index]}")