mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 19:51:51 +09:00
distinguishing zero-byte write from full-block write
This commit is contained in:
@@ -110,15 +110,17 @@ MMIO
|
||||
4080..4083 RO: 8-bit status code for connected device
|
||||
|
||||
4084..4091 RO: Block transfer status
|
||||
0b nnnnnnnn a000 mmmm
|
||||
0b nnnnnnnn a00z mmmm
|
||||
|
||||
n-read: size of the block from the other device, LSB (4096-full block size is zero)
|
||||
m-read: size of the block from the other device, MSB (4096-full block size is zero)
|
||||
a-read: if the other device hasNext (doYouHaveNext), false if device not present
|
||||
z-read: set if the size is actually 0 instead of 4096
|
||||
|
||||
n-write: size of the block I'm sending, LSB (4096-full block size is zero)
|
||||
m-write: size of the block I'm sending, MSB (4096-full block size is zero)
|
||||
a-write: if there's more to send (hasNext)
|
||||
z-write: set if the size is actually 0 instead of 4096
|
||||
|
||||
4092..4095 RW: Block transfer control for Port 1 through 4
|
||||
0b 00ms abcd
|
||||
|
||||
@@ -119,16 +119,18 @@ object SerialHelper {
|
||||
private fun setBlockTransferStatus(vm: VM, portNo: Int, blockSize: Int, moreToSend: Boolean = false) {
|
||||
vm.getIO().mmio_write(4084L + (portNo * 2), (blockSize and 255).toByte())
|
||||
vm.getIO().mmio_write(4085L + (portNo * 2),
|
||||
((blockSize ushr 8).and(15) or (moreToSend.toInt(7))).toByte()
|
||||
((blockSize ushr 8).and(15) or (moreToSend.toInt(7)) or (blockSize == 0).toInt(4)).toByte()
|
||||
)
|
||||
}
|
||||
|
||||
private fun getBlockTransferStatus(vm: VM, portNo: Int): Pair<Int, Boolean> {
|
||||
val bits = vm.getIO().mmio_read(4084L + (portNo * 2))!!.toUint() or
|
||||
(vm.getIO().mmio_read(4085L + (portNo * 2))!!.toUint() shl 8)
|
||||
val lb = vm.getIO().mmio_read(4084L + (portNo * 2))!!.toUint()
|
||||
val hb = vm.getIO().mmio_read(4085L + (portNo * 2))!!.toUint()
|
||||
val bits = lb or (hb shl 8)
|
||||
val rawcnt = bits.and(4095)
|
||||
val gotMore = bits.and(0x8000) != 0
|
||||
return (if (rawcnt == 0) BLOCK_SIZE else rawcnt) to gotMore
|
||||
val actuallyZero = (hb and 0x10 != 0)
|
||||
return (if (rawcnt == 0 && !actuallyZero) BLOCK_SIZE else rawcnt) to gotMore
|
||||
}
|
||||
|
||||
data class DeviceStatus(val code: Int, val message: String)
|
||||
|
||||
@@ -129,13 +129,13 @@ class IOSpace(val vm: VM) : PeriBase("io"), InputProcessor {
|
||||
4083L -> blockTransferPorts[3].getYourStatusCode().toByte()
|
||||
|
||||
4084L -> (blockTransferPorts[0].yourBlockSize().toByte())
|
||||
4085L -> (blockTransferPorts[0].doYouHaveNext().toInt(7) or blockTransferPorts[0].yourBlockSize().ushr(8).and(15)).toByte()
|
||||
4085L -> (blockTransferPorts[0].doYouHaveNext().toInt(7) or (blockTransferPorts[0].yourBlockSize() == 0).toInt(4) or blockTransferPorts[0].yourBlockSize().ushr(8).and(15)).toByte()
|
||||
4086L -> (blockTransferPorts[1].yourBlockSize().toByte())
|
||||
4087L -> (blockTransferPorts[1].doYouHaveNext().toInt(7) or blockTransferPorts[1].yourBlockSize().ushr(8).and(15)).toByte()
|
||||
4087L -> (blockTransferPorts[1].doYouHaveNext().toInt(7) or (blockTransferPorts[1].yourBlockSize() == 0).toInt(4) or blockTransferPorts[1].yourBlockSize().ushr(8).and(15)).toByte()
|
||||
4088L -> (blockTransferPorts[2].yourBlockSize().toByte())
|
||||
4089L -> (blockTransferPorts[2].doYouHaveNext().toInt(7) or blockTransferPorts[2].yourBlockSize().ushr(8).and(15)).toByte()
|
||||
4089L -> (blockTransferPorts[2].doYouHaveNext().toInt(7) or (blockTransferPorts[2].yourBlockSize() == 0).toInt(4) or blockTransferPorts[2].yourBlockSize().ushr(8).and(15)).toByte()
|
||||
4090L -> (blockTransferPorts[3].yourBlockSize().toByte())
|
||||
4091L -> (blockTransferPorts[3].doYouHaveNext().toInt(7) or blockTransferPorts[3].yourBlockSize().ushr(8).and(15)).toByte()
|
||||
4091L -> (blockTransferPorts[3].doYouHaveNext().toInt(7) or (blockTransferPorts[3].yourBlockSize() == 0).toInt(4) or blockTransferPorts[3].yourBlockSize().ushr(8).and(15)).toByte()
|
||||
|
||||
in 4092..4095 -> composeBlockTransferStatus(adi - 4092).toByte()
|
||||
|
||||
@@ -196,7 +196,7 @@ class IOSpace(val vm: VM) : PeriBase("io"), InputProcessor {
|
||||
4085L -> {
|
||||
blockTransferPorts[0].hasNext.set(byte < 0)
|
||||
blockTransferPorts[0].blockSize.getAcquire().let {
|
||||
blockTransferPorts[0].blockSize.setRelease(it.and(0x00FF) or byte.toInt().and(15))
|
||||
blockTransferPorts[0].blockSize.setRelease(it.and(0x00FF) or byte.toInt().and(15) or (it == 0).toInt(4))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ class IOSpace(val vm: VM) : PeriBase("io"), InputProcessor {
|
||||
4087L -> {
|
||||
blockTransferPorts[1].hasNext.set(byte < 0)
|
||||
blockTransferPorts[1].blockSize.getAcquire().let {
|
||||
blockTransferPorts[1].blockSize.setRelease(it.and(0x00FF) or byte.toInt().and(15))
|
||||
blockTransferPorts[1].blockSize.setRelease(it.and(0x00FF) or byte.toInt().and(15) or (it == 0).toInt(4))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ class IOSpace(val vm: VM) : PeriBase("io"), InputProcessor {
|
||||
4089L -> {
|
||||
blockTransferPorts[2].hasNext.set(byte < 0)
|
||||
blockTransferPorts[2].blockSize.getAcquire().let {
|
||||
blockTransferPorts[2].blockSize.setRelease(it.and(0x00FF) or byte.toInt().and(15))
|
||||
blockTransferPorts[2].blockSize.setRelease(it.and(0x00FF) or byte.toInt().and(15) or (it == 0).toInt(4))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ class IOSpace(val vm: VM) : PeriBase("io"), InputProcessor {
|
||||
4091L -> {
|
||||
blockTransferPorts[3].hasNext.set(byte < 0)
|
||||
blockTransferPorts[3].blockSize.getAcquire().let {
|
||||
blockTransferPorts[3].blockSize.setRelease(it.and(0x00FF) or byte.toInt().and(15))
|
||||
blockTransferPorts[3].blockSize.setRelease(it.and(0x00FF) or byte.toInt().and(15) or (it == 0).toInt(4))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -143,23 +143,38 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, theTevdPath:
|
||||
//println("[DiskDrive] writeout with inputdata length of ${inputData.size}")
|
||||
//println("[DiskDriveMsg] ${inputData.toString(Charsets.UTF_8)}")
|
||||
|
||||
println("[TevDiskDrive] write-payload (${inputData.size} bytes)")
|
||||
|
||||
|
||||
if (!fileOpen) throw InternalError("File is not open but the drive is in write mode")
|
||||
|
||||
System.arraycopy(inputData, 0, writeBuffer, writeBufferUsage, minOf(writeModeLength - writeBufferUsage, inputData.size, BLOCK_SIZE))
|
||||
writeBufferUsage += inputData.size
|
||||
|
||||
if (writeBufferUsage >= writeModeLength) {
|
||||
// commit to the disk
|
||||
if (appendMode) {
|
||||
val filesize = file.length()
|
||||
file.pwrite(writeBuffer, 0, writeBuffer.size, filesize)
|
||||
}
|
||||
else if (writeMode)
|
||||
file.overwrite(writeBuffer)
|
||||
|
||||
if (writeBuffer.isEmpty()) {
|
||||
writeMode = false
|
||||
appendMode = false
|
||||
}
|
||||
else {
|
||||
System.arraycopy(
|
||||
inputData,
|
||||
0,
|
||||
writeBuffer,
|
||||
writeBufferUsage,
|
||||
minOf(writeModeLength - writeBufferUsage, inputData.size, BLOCK_SIZE)
|
||||
)
|
||||
writeBufferUsage += inputData.size
|
||||
|
||||
if (writeBufferUsage >= writeModeLength) {
|
||||
// commit to the disk
|
||||
if (appendMode) {
|
||||
val filesize = file.length()
|
||||
file.pwrite(writeBuffer, 0, writeBuffer.size, filesize)
|
||||
}
|
||||
else if (writeMode)
|
||||
file.overwrite(writeBuffer)
|
||||
|
||||
writeMode = false
|
||||
appendMode = false
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (fileOpenMode == 17) {
|
||||
if (!fileOpen) throw InternalError("Bootloader file is not open but the drive is in boot write mode")
|
||||
@@ -175,7 +190,7 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, theTevdPath:
|
||||
else {
|
||||
val inputString = inputData.trimNull().toString(VM.CHARSET)
|
||||
|
||||
// println("[TevDiskDrive] $inputString")
|
||||
println("[TevDiskDrive] $inputString")
|
||||
|
||||
if (inputString.startsWith("DEVRST\u0017")) {
|
||||
printdbg("Device Reset")
|
||||
@@ -430,6 +445,7 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, theTevdPath:
|
||||
}
|
||||
}
|
||||
else if (inputString.startsWith("WRITE")) {
|
||||
writeModeLength = inputString.substring(5, inputString.length).toInt()
|
||||
if (!fileOpen) {
|
||||
statusCode.set(STATE_CODE_NO_FILE_OPENED)
|
||||
return
|
||||
@@ -440,7 +456,6 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, theTevdPath:
|
||||
}
|
||||
if (fileOpenMode == 1) { writeMode = true; appendMode = false }
|
||||
else if (fileOpenMode == 2) { writeMode = false; appendMode = true }
|
||||
writeModeLength = inputString.substring(5, inputString.length).toInt()
|
||||
writeBuffer = ByteArray(writeModeLength)
|
||||
writeBufferUsage = 0
|
||||
statusCode.set(STATE_CODE_STANDBY)
|
||||
|
||||
Reference in New Issue
Block a user