distinguishing zero-byte write from full-block write

This commit is contained in:
minjaesong
2023-06-15 23:30:57 +09:00
parent 445c1a873f
commit 974be9dda6
4 changed files with 46 additions and 27 deletions

View File

@@ -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)

View File

@@ -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))
}
}

View File

@@ -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)