Skip to content

Commit 8e5ef8f

Browse files
committed
Update socket serial bridge overrun logic
1 parent ca9f2e9 commit 8e5ef8f

File tree

2 files changed

+25
-9
lines changed

2 files changed

+25
-9
lines changed

mod/src/main/kotlin/gay/object/mlogv32/ProcessorAccess.kt

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import io.ktor.network.sockets.*
88
import io.ktor.utils.io.*
99
import kotlinx.coroutines.*
1010
import kotlinx.coroutines.CancellationException
11+
import kotlinx.io.readUByte
1112
import kotlinx.serialization.SerialName
1213
import kotlinx.serialization.Serializable
1314
import kotlinx.serialization.json.Json
@@ -21,6 +22,7 @@ import mindustry.world.blocks.logic.SwitchBlock.SwitchBuild
2122
import kotlin.concurrent.thread
2223
import kotlin.coroutines.resume
2324
import kotlin.coroutines.resumeWithException
25+
import kotlin.math.min
2426

2527
class ProcessorAccess(
2628
val build: LogicBuild,
@@ -381,10 +383,11 @@ enum class UartDevice {
381383
}
382384

383385
@Serializable
384-
@SerialName("uart")
385-
data class UartRequest(
386+
@SerialName("serial")
387+
data class SerialRequest(
386388
val device: UartDevice,
387-
val stopOnHalt: Boolean = true,
389+
val stopOnHalt: Boolean,
390+
val overrun: Boolean,
388391
) : Request() {
389392
override suspend fun handle(processor: ProcessorAccess, rx: ByteReadChannel, tx: ByteWriteChannel): Response {
390393
val uart = when (device) {
@@ -396,18 +399,28 @@ data class UartRequest(
396399
throw RuntimeException("Client disconnected!")
397400
}
398401

399-
val toUart = 0.until(rx.availableForRead).map { rx.readByte().toUByte() }
400-
if (toUart.isNotEmpty()) Log.info("Sending to $device: $toUart")
401-
402402
var overflowCount = 0
403403

404404
val fromUart = runOnMainThread {
405405
if (stopOnHalt && processor.resetSwitch.enabled) {
406406
throw RuntimeException("Processor stopped!")
407407
}
408-
for (byte in toUart) {
409-
if (!uart.write(byte)) overflowCount++
408+
409+
rx.readAvailable(1) { buffer ->
410+
val bytes = if (overrun) {
411+
buffer.size.toInt()
412+
} else {
413+
min(buffer.size.toInt(), uart.availableForWrite)
414+
}
415+
416+
for (i in 0..<bytes) {
417+
val byte = buffer.readUByte()
418+
if (!uart.write(byte, signalOverflow = overrun)) overflowCount++
419+
}
420+
421+
bytes
410422
}
423+
411424
uart.readAll()
412425
}
413426

mod/src/main/kotlin/gay/object/mlogv32/UartAccess.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ class UartAccess(private val build: MemoryBuild, private val capacity: Int) {
1212
private var rxRptr by MemoryIntDelegate(build, 510)
1313
private val rxWptr by MemoryIntDelegate(build, 511)
1414

15+
val writeBufferSize get() = wrap(txWptr - txRptr)
16+
val availableForWrite get() = capacity - writeBufferSize
17+
1518
fun readAll() : List<UByte>{
1619
val result = mutableListOf<UByte>()
1720
while (true) {
@@ -30,7 +33,7 @@ class UartAccess(private val build: MemoryBuild, private val capacity: Int) {
3033
return byte
3134
}
3235

33-
fun write(byte: UByte, signalOverflow: Boolean = true): Boolean {
36+
fun write(byte: UByte, signalOverflow: Boolean): Boolean {
3437
val nextWptr = wrap(txWptr + 1)
3538

3639
// full, maybe signal overflow

0 commit comments

Comments
 (0)