a t o m i q u e

This commit is contained in:
minjaesong
2022-12-17 21:19:53 +09:00
parent 5aa275fa77
commit e1e1a2f5db
8 changed files with 148 additions and 134 deletions

View File

@@ -1,18 +1,19 @@
package net.torvald.tsvm.peripheral package net.torvald.tsvm.peripheral
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger
abstract class BlockTransferInterface(val isMaster: Boolean, val isSlave: Boolean) { abstract class BlockTransferInterface(val isMaster: Boolean, val isSlave: Boolean) {
protected var recipient: BlockTransferInterface? = null protected var recipient: BlockTransferInterface? = null
@Volatile val ready = AtomicBoolean(true) val ready = AtomicBoolean(true)
@Volatile val busy = AtomicBoolean(false) val busy = AtomicBoolean(false)
@Volatile var statusCode = 0 val statusCode = AtomicInteger(0)
protected var sendmode = false; private set protected var sendmode = false; private set
@Volatile var blockSize = 0 val blockSize = AtomicInteger(0)
open fun attachDevice(device: BlockTransferInterface?) { open fun attachDevice(device: BlockTransferInterface?) {
recipient = device recipient = device
@@ -33,7 +34,7 @@ abstract class BlockTransferInterface(val isMaster: Boolean, val isSlave: Boolea
ready.setRelease(false) ready.setRelease(false)
recipient?.let { recipient?.let {
this.blockSize = startSendImpl(it) this.blockSize.set(startSendImpl(it))
//println("[BlockTransferInterface.startSend()] recipients blocksize = ${this.blockSize}") //println("[BlockTransferInterface.startSend()] recipients blocksize = ${this.blockSize}")
} }
@@ -59,14 +60,14 @@ abstract class BlockTransferInterface(val isMaster: Boolean, val isSlave: Boolea
fun writeout(inputData: ByteArray) { fun writeout(inputData: ByteArray) {
busy.setRelease(true) busy.setRelease(true)
ready.setRelease(false) ready.setRelease(false)
blockSize = minOf(inputData.size, BLOCK_SIZE) blockSize.setRelease(minOf(inputData.size, BLOCK_SIZE))
writeoutImpl(inputData) writeoutImpl(inputData)
busy.setRelease(false) busy.setRelease(false)
ready.setRelease(true) ready.setRelease(true)
} }
abstract fun hasNext(): Boolean abstract fun hasNext(): Boolean
open fun doYouHaveNext(): Boolean = recipient?.hasNext() ?: false open fun doYouHaveNext(): Boolean = recipient?.hasNext() ?: false
open fun yourBlockSize(): Int = recipient?.blockSize ?: 0 open fun yourBlockSize(): Int = recipient?.blockSize?.get() ?: 0
fun getYourStatusCode() = recipient?.statusCode ?: 0 fun getYourStatusCode() = recipient?.statusCode ?: 0

View File

@@ -2,20 +2,21 @@ package net.torvald.tsvm.peripheral
import net.torvald.UnsafeHelper import net.torvald.UnsafeHelper
import net.torvald.tsvm.VM import net.torvald.tsvm.VM
import java.util.concurrent.atomic.AtomicBoolean
/** /**
* Implementation of single COM port * Implementation of single COM port
*/ */
class BlockTransferPort(val vm: VM, val portno: Int) : BlockTransferInterface(true, false) { class BlockTransferPort(val vm: VM, val portno: Int) : BlockTransferInterface(true, false) {
internal var hasNext = false val hasNext = AtomicBoolean(false)
override fun startSendImpl(recipient: BlockTransferInterface): Int { override fun startSendImpl(recipient: BlockTransferInterface): Int {
recipient.writeout(ByteArray(BLOCK_SIZE) { vm.getIO().blockTransferTx[portno][it.toLong()] }) recipient.writeout(ByteArray(BLOCK_SIZE) { vm.getIO().blockTransferTx[portno][it.toLong()] })
return blockSize // use MMIO to modify this variable return blockSize.get() // use MMIO to modify this variable
} }
override fun hasNext(): Boolean = hasNext override fun hasNext(): Boolean = hasNext.get()
override fun writeoutImpl(inputData: ByteArray) { override fun writeoutImpl(inputData: ByteArray) {
//val copySize = minOf(BLOCK_SIZE, inputData.size).toLong() //val copySize = minOf(BLOCK_SIZE, inputData.size).toLong()

View File

@@ -40,7 +40,7 @@ class HttpModem(private val vm: VM, private val artificialDelayBlockSize: Int =
init { init {
statusCode = TestDiskDrive.STATE_CODE_STANDBY statusCode.set(TestDiskDrive.STATE_CODE_STANDBY)
} }
override fun hasNext(): Boolean { override fun hasNext(): Boolean {
@@ -105,17 +105,17 @@ class HttpModem(private val vm: VM, private val artificialDelayBlockSize: Int =
if (inputString.startsWith("DEVRST\u0017")) { if (inputString.startsWith("DEVRST\u0017")) {
printdbg("Device Reset") printdbg("Device Reset")
selfReset() selfReset()
statusCode = TestDiskDrive.STATE_CODE_STANDBY statusCode.set(TestDiskDrive.STATE_CODE_STANDBY)
} }
else if (inputString.startsWith("DEVSTU\u0017")) else if (inputString.startsWith("DEVSTU\u0017"))
recipient?.writeout(composePositiveAns("${statusCode.toChar()}", TestDiskDrive.errorMsgs[statusCode])) recipient?.writeout(composePositiveAns("${statusCode.get().toChar()}", TestDiskDrive.errorMsgs[statusCode.get()]))
else if (inputString.startsWith("DEVTYP\u0017")) else if (inputString.startsWith("DEVTYP\u0017"))
recipient?.writeout(composePositiveAns("HTTP")) recipient?.writeout(composePositiveAns("HTTP"))
else if (inputString.startsWith("DEVNAM\u0017")) else if (inputString.startsWith("DEVNAM\u0017"))
recipient?.writeout(composePositiveAns("Wget Company HTTP Modem")) recipient?.writeout(composePositiveAns("Wget Company HTTP Modem"))
else if (inputString.startsWith("GET ")) { else if (inputString.startsWith("GET ")) {
if (cnxUrl != null) { if (cnxUrl != null) {
statusCode = TestDiskDrive.STATE_CODE_FILE_ALREADY_OPENED statusCode.set(TestDiskDrive.STATE_CODE_FILE_ALREADY_OPENED)
return return
} }
@@ -127,8 +127,8 @@ class HttpModem(private val vm: VM, private val artificialDelayBlockSize: Int =
printdbg("URL: $cnxUrl") printdbg("URL: $cnxUrl")
this.ready = false this.ready.setRelease(false)
this.busy = true this.busy.setRelease(true)
var httpIn: InputStream? = null var httpIn: InputStream? = null
var bufferedOut: OutputStream? = null var bufferedOut: OutputStream? = null
@@ -156,14 +156,14 @@ class HttpModem(private val vm: VM, private val artificialDelayBlockSize: Int =
catch (e: InterruptedException) {} catch (e: InterruptedException) {}
} }
} }
statusCode = TestDiskDrive.STATE_CODE_STANDBY statusCode.set(TestDiskDrive.STATE_CODE_STANDBY)
} }
catch (e: MalformedURLException) { catch (e: MalformedURLException) {
statusCode = STATE_CODE_NO_SUCH_FILE_EXISTS // MalformedUrl statusCode.set(STATE_CODE_NO_SUCH_FILE_EXISTS) // MalformedUrl
printdbg("Malformed URL: $cnxUrl") printdbg("Malformed URL: $cnxUrl")
} }
catch (e: IOException) { catch (e: IOException) {
statusCode = STATE_CODE_SYSTEM_IO_ERROR // IoException statusCode.set(STATE_CODE_SYSTEM_IO_ERROR) // IoException
printdbg("IOException: $cnxUrl") printdbg("IOException: $cnxUrl")
} }
finally { finally {
@@ -173,7 +173,7 @@ class HttpModem(private val vm: VM, private val artificialDelayBlockSize: Int =
httpIn?.close() httpIn?.close()
} }
catch (e: IOException) { catch (e: IOException) {
statusCode = STATE_CODE_OPERATION_FAILED // UnableToCloseOutputStream statusCode.set(STATE_CODE_OPERATION_FAILED) // UnableToCloseOutputStream
printdbg("Unable to close: $cnxUrl") printdbg("Unable to close: $cnxUrl")
} }
finally { finally {
@@ -183,7 +183,7 @@ class HttpModem(private val vm: VM, private val artificialDelayBlockSize: Int =
} }
} }
else else
statusCode = TestDiskDrive.STATE_CODE_ILLEGAL_COMMAND statusCode.set(TestDiskDrive.STATE_CODE_ILLEGAL_COMMAND)
} }

View File

@@ -56,14 +56,14 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor {
return blockTransferPorts[portno].isMaster.toInt().shl(5) or return blockTransferPorts[portno].isMaster.toInt().shl(5) or
blockTransferPorts[portno].isSlave.toInt().shl(4) or blockTransferPorts[portno].isSlave.toInt().shl(4) or
blockTransferPorts[portno].getMode().toInt().shl(3) or blockTransferPorts[portno].getMode().toInt().shl(3) or
blockTransferPorts[portno].busy.toInt().shl(2) or blockTransferPorts[portno].busy.get().toInt().shl(2) or
blockTransferPorts[portno].areYouReady().toInt().shl(1) or blockTransferPorts[portno].areYouReady().toInt().shl(1) or
blockTransferPorts[portno].cableConnected().toInt() blockTransferPorts[portno].cableConnected().toInt()
} }
private fun setBlockTransferPortStatus(portno: Int, bits: Byte) { private fun setBlockTransferPortStatus(portno: Int, bits: Byte) {
blockTransferPorts[portno].setMode(bits.and(0b0000_1000) != 0.toByte()) blockTransferPorts[portno].setMode(bits.and(0b0000_1000) != 0.toByte())
blockTransferPorts[portno].ready = bits.and(0b0000_0010) != 0.toByte() blockTransferPorts[portno].ready.set(bits.and(0b0000_0010) != 0.toByte())
if (bits.and(0b0000_0100) != 0.toByte()) { if (bits.and(0b0000_0100) != 0.toByte()) {
if (blockTransferPorts[portno].getMode()) { if (blockTransferPorts[portno].getMode()) {
//println("[IOSpace] startSend()") //println("[IOSpace] startSend()")
@@ -167,30 +167,42 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor {
in 1024..2047 -> peripheralFast[addr - 1024] = byte in 1024..2047 -> peripheralFast[addr - 1024] = byte
4076L -> blockTransferPorts[0].statusCode = bi 4076L -> blockTransferPorts[0].statusCode.set(bi)
4077L -> blockTransferPorts[1].statusCode = bi 4077L -> blockTransferPorts[1].statusCode.set(bi)
4078L -> blockTransferPorts[2].statusCode = bi 4078L -> blockTransferPorts[2].statusCode.set(bi)
4079L -> blockTransferPorts[3].statusCode = bi 4079L -> blockTransferPorts[3].statusCode.set(bi)
4084L -> blockTransferPorts[0].blockSize = blockTransferPorts[0].blockSize.and(0xFF00) or byte.toInt().and(255) 4084L ->
blockTransferPorts[0].blockSize.getAcquire().let {
blockTransferPorts[0].blockSize.setRelease(it.and(0xFF00) or byte.toInt().and(255)) }
4085L -> { 4085L -> {
blockTransferPorts[0].hasNext = (byte < 0) blockTransferPorts[0].hasNext.set(byte < 0)
blockTransferPorts[0].blockSize = blockTransferPorts[0].blockSize.and(0x00FF) or byte.toInt().and(15) blockTransferPorts[0].blockSize.getAcquire().let {
blockTransferPorts[0].blockSize.setRelease(it.and(0x00FF) or byte.toInt().and(15)) }
} }
4086L -> blockTransferPorts[1].blockSize = blockTransferPorts[1].blockSize.and(0xFF00) or byte.toInt().and(255)
4086L -> blockTransferPorts[1].blockSize.getAcquire().let {
blockTransferPorts[1].blockSize.setRelease(it.and(0xFF00) or byte.toInt().and(255)) }
4087L -> { 4087L -> {
blockTransferPorts[1].hasNext = (byte < 0) blockTransferPorts[1].hasNext.set(byte < 0)
blockTransferPorts[1].blockSize = blockTransferPorts[1].blockSize.and(0x00FF) or byte.toInt().and(15) blockTransferPorts[1].blockSize.getAcquire().let {
blockTransferPorts[1].blockSize.setRelease(it.and(0x00FF) or byte.toInt().and(15)) }
} }
4088L -> blockTransferPorts[2].blockSize = blockTransferPorts[2].blockSize.and(0xFF00) or byte.toInt().and(255)
4088L -> blockTransferPorts[2].blockSize.getAcquire().let {
blockTransferPorts[2].blockSize.setRelease(it.and(0xFF00) or byte.toInt().and(255)) }
4089L -> { 4089L -> {
blockTransferPorts[2].hasNext = (byte < 0) blockTransferPorts[2].hasNext.set(byte < 0)
blockTransferPorts[2].blockSize = blockTransferPorts[2].blockSize.and(0x00FF) or byte.toInt().and(15) blockTransferPorts[2].blockSize.getAcquire().let {
blockTransferPorts[2].blockSize.setRelease(it.and(0x00FF) or byte.toInt().and(15)) }
} }
4090L -> blockTransferPorts[3].blockSize = blockTransferPorts[3].blockSize.and(0xFF00) or byte.toInt().and(255)
4090L -> blockTransferPorts[3].blockSize.getAcquire().let {
blockTransferPorts[3].blockSize.setRelease(it.and(0xFF00) or byte.toInt().and(255)) }
4091L -> { 4091L -> {
blockTransferPorts[3].hasNext = (byte < 0) blockTransferPorts[3].hasNext.set(byte < 0)
blockTransferPorts[3].blockSize = blockTransferPorts[3].blockSize.and(0x00FF) or byte.toInt().and(15) blockTransferPorts[3].blockSize.getAcquire().let {
blockTransferPorts[3].blockSize.setRelease(it.and(0x00FF) or byte.toInt().and(15)) }
} }
in 4092..4095 -> setBlockTransferPortStatus(adi - 4092, byte) in 4092..4095 -> setBlockTransferPortStatus(adi - 4092, byte)

View File

@@ -79,7 +79,7 @@ class TestDiskDrive(private val vm: VM, private val driveNum: Int, theRootPath:
init { init {
statusCode = STATE_CODE_STANDBY statusCode.set(STATE_CODE_STANDBY)
if (!rootPath.exists()) { if (!rootPath.exists()) {
rootPath.mkdirs() rootPath.mkdirs()
@@ -160,12 +160,12 @@ class TestDiskDrive(private val vm: VM, private val driveNum: Int, theRootPath:
fileOpenMode = -1 fileOpenMode = -1
file = File(rootPath.toURI()) file = File(rootPath.toURI())
blockSendCount = 0 blockSendCount = 0
statusCode = STATE_CODE_STANDBY statusCode.set(STATE_CODE_STANDBY)
writeMode = false writeMode = false
writeModeLength = -1 writeModeLength = -1
} }
else if (inputString.startsWith("DEVSTU\u0017")) else if (inputString.startsWith("DEVSTU\u0017"))
recipient?.writeout(composePositiveAns("${statusCode.toChar()}", errorMsgs[statusCode])) recipient?.writeout(composePositiveAns("${statusCode.get().toChar()}", errorMsgs[statusCode.get()]))
else if (inputString.startsWith("DEVTYP\u0017")) else if (inputString.startsWith("DEVTYP\u0017"))
recipient?.writeout(composePositiveAns("STOR")) recipient?.writeout(composePositiveAns("STOR"))
else if (inputString.startsWith("DEVNAM\u0017")) else if (inputString.startsWith("DEVNAM\u0017"))
@@ -173,7 +173,7 @@ class TestDiskDrive(private val vm: VM, private val driveNum: Int, theRootPath:
else if (inputString.startsWith("OPENR\"") || inputString.startsWith("OPENW\"") || inputString.startsWith("OPENA\"")) { else if (inputString.startsWith("OPENR\"") || inputString.startsWith("OPENW\"") || inputString.startsWith("OPENA\"")) {
if (fileOpen) { if (fileOpen) {
statusCode = STATE_CODE_FILE_ALREADY_OPENED statusCode.set(STATE_CODE_FILE_ALREADY_OPENED)
return return
} }
@@ -190,7 +190,7 @@ class TestDiskDrive(private val vm: VM, private val driveNum: Int, theRootPath:
} }
// sanity check if path is actually enclosed with double-quote // sanity check if path is actually enclosed with double-quote
if (commaIndex != 6 && inputString[commaIndex - 1] != '"') { if (commaIndex != 6 && inputString[commaIndex - 1] != '"') {
statusCode = STATE_CODE_ILLEGAL_COMMAND statusCode.set(STATE_CODE_ILLEGAL_COMMAND)
return return
} }
val pathStr = inputString.substring(6, if (commaIndex == 6) inputString.lastIndex else commaIndex - 1) val pathStr = inputString.substring(6, if (commaIndex == 6) inputString.lastIndex else commaIndex - 1)
@@ -205,11 +205,11 @@ class TestDiskDrive(private val vm: VM, private val driveNum: Int, theRootPath:
if (openMode == 'R' && !file.exists()) { if (openMode == 'R' && !file.exists()) {
printdbg("! file not found") printdbg("! file not found")
statusCode = STATE_CODE_NO_SUCH_FILE_EXISTS statusCode.set(STATE_CODE_NO_SUCH_FILE_EXISTS)
return return
} }
statusCode = STATE_CODE_STANDBY statusCode.set(STATE_CODE_STANDBY)
fileOpen = true fileOpen = true
fileOpenMode = when (openMode) { fileOpenMode = when (openMode) {
'W' -> 1 'W' -> 1
@@ -220,18 +220,18 @@ class TestDiskDrive(private val vm: VM, private val driveNum: Int, theRootPath:
} }
else if (inputString.startsWith("DELETE")) { else if (inputString.startsWith("DELETE")) {
if (!fileOpen) { if (!fileOpen) {
statusCode = STATE_CODE_NO_FILE_OPENED statusCode.set(STATE_CODE_NO_FILE_OPENED)
return return
} }
try { try {
file.delete() file.delete()
} }
catch (e: SecurityException) { catch (e: SecurityException) {
statusCode = STATE_CODE_SYSTEM_SECURITY_ERROR statusCode.set(STATE_CODE_SYSTEM_SECURITY_ERROR)
return return
} }
catch (e1: IOException) { catch (e1: IOException) {
statusCode = STATE_CODE_SYSTEM_IO_ERROR statusCode.set(STATE_CODE_SYSTEM_IO_ERROR)
return return
} }
} }
@@ -239,7 +239,7 @@ class TestDiskDrive(private val vm: VM, private val driveNum: Int, theRootPath:
// TODO temporary behaviour to ignore any arguments // TODO temporary behaviour to ignore any arguments
resetBuf() resetBuf()
if (!fileOpen) { if (!fileOpen) {
statusCode = STATE_CODE_NO_FILE_OPENED statusCode.set(STATE_CODE_NO_FILE_OPENED)
return return
} }
try { try {
@@ -250,19 +250,19 @@ class TestDiskDrive(private val vm: VM, private val driveNum: Int, theRootPath:
messageComposeBuffer.write(lsfile.name.toByteArray(VM.CHARSET)) messageComposeBuffer.write(lsfile.name.toByteArray(VM.CHARSET))
} }
statusCode = STATE_CODE_STANDBY statusCode.set(STATE_CODE_STANDBY)
} }
else { else {
statusCode = STATE_CODE_NOT_A_DIRECTORY statusCode.set(STATE_CODE_NOT_A_DIRECTORY)
return return
} }
} }
catch (e: SecurityException) { catch (e: SecurityException) {
statusCode = STATE_CODE_SYSTEM_SECURITY_ERROR statusCode.set(STATE_CODE_SYSTEM_SECURITY_ERROR)
return return
} }
catch (e1: IOException) { catch (e1: IOException) {
statusCode = STATE_CODE_SYSTEM_IO_ERROR statusCode.set(STATE_CODE_SYSTEM_IO_ERROR)
return return
} }
} }
@@ -270,28 +270,28 @@ class TestDiskDrive(private val vm: VM, private val driveNum: Int, theRootPath:
// TODO temporary behaviour to ignore any arguments // TODO temporary behaviour to ignore any arguments
resetBuf() resetBuf()
if (!fileOpen) { if (!fileOpen) {
statusCode = STATE_CODE_NO_FILE_OPENED statusCode.set(STATE_CODE_NO_FILE_OPENED)
return return
} }
messageComposeBuffer.write(getSizeStr().toByteArray(VM.CHARSET)) messageComposeBuffer.write(getSizeStr().toByteArray(VM.CHARSET))
statusCode = STATE_CODE_STANDBY statusCode.set(STATE_CODE_STANDBY)
} }
else if (inputString.startsWith("LIST")) { else if (inputString.startsWith("LIST")) {
// TODO temporary behaviour to ignore any arguments // TODO temporary behaviour to ignore any arguments
resetBuf() resetBuf()
if (!fileOpen) { if (!fileOpen) {
statusCode = STATE_CODE_NO_FILE_OPENED statusCode.set(STATE_CODE_NO_FILE_OPENED)
return return
} }
messageComposeBuffer.write(getReadableLs().toByteArray(VM.CHARSET)) messageComposeBuffer.write(getReadableLs().toByteArray(VM.CHARSET))
statusCode = STATE_CODE_STANDBY statusCode.set(STATE_CODE_STANDBY)
} }
else if (inputString.startsWith("CLOSE")) { else if (inputString.startsWith("CLOSE")) {
fileOpen = false fileOpen = false
fileOpenMode = -1 fileOpenMode = -1
statusCode = STATE_CODE_STANDBY statusCode.set(STATE_CODE_STANDBY)
} }
else if (inputString.startsWith("READ")) { else if (inputString.startsWith("READ")) {
//readModeLength = inputString.substring(4 until inputString.length).toInt() //readModeLength = inputString.substring(4 until inputString.length).toInt()
@@ -300,14 +300,14 @@ class TestDiskDrive(private val vm: VM, private val driveNum: Int, theRootPath:
if (file.isFile) { if (file.isFile) {
try { try {
messageComposeBuffer.write(file.readBytes()) messageComposeBuffer.write(file.readBytes())
statusCode = STATE_CODE_STANDBY statusCode.set(STATE_CODE_STANDBY)
} }
catch (e: IOException) { catch (e: IOException) {
statusCode = STATE_CODE_SYSTEM_IO_ERROR statusCode.set(STATE_CODE_SYSTEM_IO_ERROR)
} }
} }
else { else {
statusCode = STATE_CODE_OPERATION_NOT_PERMITTED statusCode.set(STATE_CODE_OPERATION_NOT_PERMITTED)
return return
} }
} }
@@ -324,7 +324,7 @@ class TestDiskDrive(private val vm: VM, private val driveNum: Int, theRootPath:
val bootFile = File(rootPath, "!BOOTSEC") val bootFile = File(rootPath, "!BOOTSEC")
if (!bootFile.exists()) { if (!bootFile.exists()) {
statusCode = STATE_CODE_NO_SUCH_FILE_EXISTS statusCode.set(STATE_CODE_NO_SUCH_FILE_EXISTS)
return return
} }
val fis = FileInputStream(bootFile) val fis = FileInputStream(bootFile)
@@ -332,10 +332,10 @@ class TestDiskDrive(private val vm: VM, private val driveNum: Int, theRootPath:
val retMsg = ByteArray(BLOCK_SIZE) val retMsg = ByteArray(BLOCK_SIZE)
fis.read(retMsg) fis.read(retMsg)
recipient?.writeout(retMsg) recipient?.writeout(retMsg)
statusCode = STATE_CODE_STANDBY statusCode.set(STATE_CODE_STANDBY)
} }
catch (e: IOException) { catch (e: IOException) {
statusCode = STATE_CODE_SYSTEM_IO_ERROR statusCode.set(STATE_CODE_SYSTEM_IO_ERROR)
return return
} }
finally { finally {
@@ -344,70 +344,70 @@ class TestDiskDrive(private val vm: VM, private val driveNum: Int, theRootPath:
} }
else if (inputString.startsWith("MKDIR")) { else if (inputString.startsWith("MKDIR")) {
if (!fileOpen) { if (!fileOpen) {
statusCode = STATE_CODE_NO_FILE_OPENED statusCode.set(STATE_CODE_NO_FILE_OPENED)
return return
} }
if (fileOpenMode < 1) { if (fileOpenMode < 1) {
statusCode = STATE_CODE_OPERATION_NOT_PERMITTED statusCode.set(STATE_CODE_OPERATION_NOT_PERMITTED)
return return
} }
try { try {
val status = file.mkdir() val status = file.mkdir()
statusCode = if (status) 0 else 1 statusCode.set(if (status) 0 else 1)
} }
catch (e: SecurityException) { catch (e: SecurityException) {
statusCode = STATE_CODE_SYSTEM_SECURITY_ERROR statusCode.set(STATE_CODE_SYSTEM_SECURITY_ERROR)
} }
} }
else if (inputString.startsWith("MKFILE")) { else if (inputString.startsWith("MKFILE")) {
if (!fileOpen) { if (!fileOpen) {
statusCode = STATE_CODE_NO_FILE_OPENED statusCode.set(STATE_CODE_NO_FILE_OPENED)
return return
} }
if (fileOpenMode < 1) { if (fileOpenMode < 1) {
statusCode = STATE_CODE_OPERATION_NOT_PERMITTED statusCode.set(STATE_CODE_OPERATION_NOT_PERMITTED)
return return
} }
try { try {
val f1 = file.createNewFile() val f1 = file.createNewFile()
statusCode = if (f1) STATE_CODE_STANDBY else STATE_CODE_OPERATION_FAILED statusCode.set(if (f1) STATE_CODE_STANDBY else STATE_CODE_OPERATION_FAILED)
return return
} }
catch (e: IOException) { catch (e: IOException) {
statusCode = STATE_CODE_SYSTEM_IO_ERROR statusCode.set(STATE_CODE_SYSTEM_IO_ERROR)
} }
catch (e1: SecurityException) { catch (e1: SecurityException) {
statusCode = STATE_CODE_SYSTEM_SECURITY_ERROR statusCode.set(STATE_CODE_SYSTEM_SECURITY_ERROR)
} }
} }
else if (inputString.startsWith("TOUCH")) { else if (inputString.startsWith("TOUCH")) {
if (!fileOpen) { if (!fileOpen) {
statusCode = STATE_CODE_NO_FILE_OPENED statusCode.set(STATE_CODE_NO_FILE_OPENED)
return return
} }
if (fileOpenMode < 1) { if (fileOpenMode < 1) {
statusCode = STATE_CODE_OPERATION_NOT_PERMITTED statusCode.set(STATE_CODE_OPERATION_NOT_PERMITTED)
return return
} }
try { try {
val f1 = file.setLastModified(vm.worldInterface.currentTimeInMills()) val f1 = file.setLastModified(vm.worldInterface.currentTimeInMills())
statusCode = if (f1) STATE_CODE_STANDBY else STATE_CODE_OPERATION_FAILED statusCode.set(if (f1) STATE_CODE_STANDBY else STATE_CODE_OPERATION_FAILED)
return return
} }
catch (e: IOException) { catch (e: IOException) {
statusCode = STATE_CODE_SYSTEM_IO_ERROR statusCode.set(STATE_CODE_SYSTEM_IO_ERROR)
} }
catch (e1: SecurityException) { catch (e1: SecurityException) {
statusCode = STATE_CODE_SYSTEM_SECURITY_ERROR statusCode.set(STATE_CODE_SYSTEM_SECURITY_ERROR)
} }
} }
else if (inputString.startsWith("WRITE")) { else if (inputString.startsWith("WRITE")) {
if (!fileOpen) { if (!fileOpen) {
statusCode = STATE_CODE_NO_FILE_OPENED statusCode.set(STATE_CODE_NO_FILE_OPENED)
return return
} }
if (fileOpenMode < 0) { if (fileOpenMode < 0) {
statusCode = STATE_CODE_OPERATION_NOT_PERMITTED statusCode.set(STATE_CODE_OPERATION_NOT_PERMITTED)
return return
} }
if (fileOpenMode == 1) { writeMode = true; appendMode = false } if (fileOpenMode == 1) { writeMode = true; appendMode = false }
@@ -415,10 +415,10 @@ class TestDiskDrive(private val vm: VM, private val driveNum: Int, theRootPath:
writeModeLength = inputString.substring(5, inputString.length).toInt() writeModeLength = inputString.substring(5, inputString.length).toInt()
writeBuffer = ByteArray(writeModeLength) writeBuffer = ByteArray(writeModeLength)
writeBufferUsage = 0 writeBufferUsage = 0
statusCode = STATE_CODE_STANDBY statusCode.set(STATE_CODE_STANDBY)
} }
else else
statusCode = STATE_CODE_ILLEGAL_COMMAND statusCode.set(STATE_CODE_ILLEGAL_COMMAND)
} }
} }

View File

@@ -169,10 +169,10 @@ Nunc mollis nibh vitae sapien consequat, ut vestibulum sem pharetra. Aliquam iac
else if (inputString.startsWith("WRITE")) { else if (inputString.startsWith("WRITE")) {
writeMode = true writeMode = true
writeModeLength = inputString.substring(5, inputString.length).toInt() writeModeLength = inputString.substring(5, inputString.length).toInt()
statusCode = 0 statusCode.set(0)
} }
else else
statusCode = 128 statusCode.set(128)
blockSendCount = 0 blockSendCount = 0
} }

View File

@@ -39,7 +39,7 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
private val hasChanges = AtomicBoolean(false) private val hasChanges = AtomicBoolean(false)
init { init {
statusCode = TestDiskDrive.STATE_CODE_STANDBY statusCode.set(TestDiskDrive.STATE_CODE_STANDBY)
if (!tevdPath.exists()) { if (!tevdPath.exists()) {
throw FileNotFoundException("Disk file '${theTevdPath}' not found") throw FileNotFoundException("Disk file '${theTevdPath}' not found")
@@ -148,15 +148,15 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
fileOpenMode = -1 fileOpenMode = -1
file = TevdFileDescriptor(DOM, "") file = TevdFileDescriptor(DOM, "")
blockSendCount = 0 blockSendCount = 0
statusCode = TestDiskDrive.STATE_CODE_STANDBY statusCode.set(TestDiskDrive.STATE_CODE_STANDBY)
writeMode = false writeMode = false
writeModeLength = -1 writeModeLength = -1
} }
else if (inputString.startsWith("DEVSTU\u0017")) else if (inputString.startsWith("DEVSTU\u0017"))
recipient?.writeout( recipient?.writeout(
TestDiskDrive.composePositiveAns( TestDiskDrive.composePositiveAns(
"${statusCode.toChar()}", "${statusCode.get().toChar()}",
TestDiskDrive.errorMsgs[statusCode] TestDiskDrive.errorMsgs[statusCode.get()]
) )
) )
else if (inputString.startsWith("DEVTYP\u0017")) else if (inputString.startsWith("DEVTYP\u0017"))
@@ -166,7 +166,7 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
else if (inputString.startsWith("OPENR\"") || inputString.startsWith("OPENW\"") || inputString.startsWith("OPENA\"")) { else if (inputString.startsWith("OPENR\"") || inputString.startsWith("OPENW\"") || inputString.startsWith("OPENA\"")) {
if (fileOpen) { if (fileOpen) {
statusCode = TestDiskDrive.STATE_CODE_FILE_ALREADY_OPENED statusCode.set(TestDiskDrive.STATE_CODE_FILE_ALREADY_OPENED)
return return
} }
@@ -183,7 +183,7 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
} }
// sanity check if path is actually enclosed with double-quote // sanity check if path is actually enclosed with double-quote
if (commaIndex != 6 && inputString[commaIndex - 1] != '"') { if (commaIndex != 6 && inputString[commaIndex - 1] != '"') {
statusCode = TestDiskDrive.STATE_CODE_ILLEGAL_COMMAND statusCode.set(TestDiskDrive.STATE_CODE_ILLEGAL_COMMAND)
return return
} }
val pathStr = inputString.substring(6, if (commaIndex == 6) inputString.lastIndex else commaIndex - 1) val pathStr = inputString.substring(6, if (commaIndex == 6) inputString.lastIndex else commaIndex - 1)
@@ -198,16 +198,16 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
if (openMode == 'R' && !file.exists()) { if (openMode == 'R' && !file.exists()) {
printdbg("! file not found") printdbg("! file not found")
statusCode = TestDiskDrive.STATE_CODE_NO_SUCH_FILE_EXISTS statusCode.set(TestDiskDrive.STATE_CODE_NO_SUCH_FILE_EXISTS)
return return
} }
else if (DOM.isReadOnly && (openMode == 'W' || openMode == 'A')) { else if (DOM.isReadOnly && (openMode == 'W' || openMode == 'A')) {
printdbg("! disk is read-only") printdbg("! disk is read-only")
statusCode = TestDiskDrive.STATE_CODE_READ_ONLY statusCode.set(TestDiskDrive.STATE_CODE_READ_ONLY)
return return
} }
statusCode = TestDiskDrive.STATE_CODE_STANDBY statusCode.set(TestDiskDrive.STATE_CODE_STANDBY)
fileOpen = true fileOpen = true
fileOpenMode = when (openMode) { fileOpenMode = when (openMode) {
'W' -> 1 'W' -> 1
@@ -218,7 +218,7 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
} }
else if (inputString.startsWith("DELETE")) { else if (inputString.startsWith("DELETE")) {
if (!fileOpen) { if (!fileOpen) {
statusCode = TestDiskDrive.STATE_CODE_NO_FILE_OPENED statusCode.set(TestDiskDrive.STATE_CODE_NO_FILE_OPENED)
return return
} }
try { try {
@@ -226,11 +226,11 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
hasChanges.getAndSet(true) hasChanges.getAndSet(true)
} }
catch (e: SecurityException) { catch (e: SecurityException) {
statusCode = TestDiskDrive.STATE_CODE_SYSTEM_SECURITY_ERROR statusCode.set(TestDiskDrive.STATE_CODE_SYSTEM_SECURITY_ERROR)
return return
} }
catch (e1: IOException) { catch (e1: IOException) {
statusCode = TestDiskDrive.STATE_CODE_SYSTEM_IO_ERROR statusCode.set(TestDiskDrive.STATE_CODE_SYSTEM_IO_ERROR)
return return
} }
} }
@@ -238,7 +238,7 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
// TODO temporary behaviour to ignore any arguments // TODO temporary behaviour to ignore any arguments
resetBuf() resetBuf()
if (!fileOpen) { if (!fileOpen) {
statusCode = TestDiskDrive.STATE_CODE_NO_FILE_OPENED statusCode.set(TestDiskDrive.STATE_CODE_NO_FILE_OPENED)
return return
} }
try { try {
@@ -249,19 +249,19 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
messageComposeBuffer.write(lsfile.name.toByteArray(VM.CHARSET)) messageComposeBuffer.write(lsfile.name.toByteArray(VM.CHARSET))
} }
statusCode = TestDiskDrive.STATE_CODE_STANDBY statusCode.set(TestDiskDrive.STATE_CODE_STANDBY)
} }
else { else {
statusCode = TestDiskDrive.STATE_CODE_NOT_A_DIRECTORY statusCode.set(TestDiskDrive.STATE_CODE_NOT_A_DIRECTORY)
return return
} }
} }
catch (e: SecurityException) { catch (e: SecurityException) {
statusCode = TestDiskDrive.STATE_CODE_SYSTEM_SECURITY_ERROR statusCode.set(TestDiskDrive.STATE_CODE_SYSTEM_SECURITY_ERROR)
return return
} }
catch (e1: IOException) { catch (e1: IOException) {
statusCode = TestDiskDrive.STATE_CODE_SYSTEM_IO_ERROR statusCode.set(TestDiskDrive.STATE_CODE_SYSTEM_IO_ERROR)
return return
} }
} }
@@ -269,28 +269,28 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
// TODO temporary behaviour to ignore any arguments // TODO temporary behaviour to ignore any arguments
resetBuf() resetBuf()
if (!fileOpen) { if (!fileOpen) {
statusCode = TestDiskDrive.STATE_CODE_NO_FILE_OPENED statusCode.set(TestDiskDrive.STATE_CODE_NO_FILE_OPENED)
return return
} }
messageComposeBuffer.write(getSizeStr().toByteArray(VM.CHARSET)) messageComposeBuffer.write(getSizeStr().toByteArray(VM.CHARSET))
statusCode = TestDiskDrive.STATE_CODE_STANDBY statusCode.set(TestDiskDrive.STATE_CODE_STANDBY)
} }
else if (inputString.startsWith("LIST")) { else if (inputString.startsWith("LIST")) {
// TODO temporary behaviour to ignore any arguments // TODO temporary behaviour to ignore any arguments
resetBuf() resetBuf()
if (!fileOpen) { if (!fileOpen) {
statusCode = TestDiskDrive.STATE_CODE_NO_FILE_OPENED statusCode.set(TestDiskDrive.STATE_CODE_NO_FILE_OPENED)
return return
} }
messageComposeBuffer.write(getReadableLs().toByteArray(VM.CHARSET)) messageComposeBuffer.write(getReadableLs().toByteArray(VM.CHARSET))
statusCode = TestDiskDrive.STATE_CODE_STANDBY statusCode.set(TestDiskDrive.STATE_CODE_STANDBY)
} }
else if (inputString.startsWith("CLOSE")) { else if (inputString.startsWith("CLOSE")) {
fileOpen = false fileOpen = false
fileOpenMode = -1 fileOpenMode = -1
statusCode = TestDiskDrive.STATE_CODE_STANDBY statusCode.set(TestDiskDrive.STATE_CODE_STANDBY)
} }
else if (inputString.startsWith("READ")) { else if (inputString.startsWith("READ")) {
//readModeLength = inputString.substring(4 until inputString.length).toInt() //readModeLength = inputString.substring(4 until inputString.length).toInt()
@@ -299,14 +299,14 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
if (file.isFile) { if (file.isFile) {
try { try {
messageComposeBuffer.write(file.readBytes()) messageComposeBuffer.write(file.readBytes())
statusCode = TestDiskDrive.STATE_CODE_STANDBY statusCode.set(TestDiskDrive.STATE_CODE_STANDBY)
} }
catch (e: IOException) { catch (e: IOException) {
statusCode = TestDiskDrive.STATE_CODE_SYSTEM_IO_ERROR statusCode.set(TestDiskDrive.STATE_CODE_SYSTEM_IO_ERROR)
} }
} }
else { else {
statusCode = TestDiskDrive.STATE_CODE_OPERATION_NOT_PERMITTED statusCode.set(TestDiskDrive.STATE_CODE_OPERATION_NOT_PERMITTED)
return return
} }
} }
@@ -323,88 +323,88 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
val bootFile = TevdFileDescriptor(DOM, "!BOOTSEC") val bootFile = TevdFileDescriptor(DOM, "!BOOTSEC")
if (!bootFile.exists()) { if (!bootFile.exists()) {
statusCode = TestDiskDrive.STATE_CODE_NO_SUCH_FILE_EXISTS statusCode.set(TestDiskDrive.STATE_CODE_NO_SUCH_FILE_EXISTS)
return return
} }
try { try {
val retMsg = bootFile.getHeadBytes(BLOCK_SIZE) val retMsg = bootFile.getHeadBytes(BLOCK_SIZE)
recipient?.writeout(retMsg) recipient?.writeout(retMsg)
statusCode = TestDiskDrive.STATE_CODE_STANDBY statusCode.set(TestDiskDrive.STATE_CODE_STANDBY)
} }
catch (e: IOException) { catch (e: IOException) {
statusCode = TestDiskDrive.STATE_CODE_SYSTEM_IO_ERROR statusCode.set(TestDiskDrive.STATE_CODE_SYSTEM_IO_ERROR)
return return
} }
} }
else if (inputString.startsWith("MKDIR")) { else if (inputString.startsWith("MKDIR")) {
if (!fileOpen) { if (!fileOpen) {
statusCode = TestDiskDrive.STATE_CODE_NO_FILE_OPENED statusCode.set(TestDiskDrive.STATE_CODE_NO_FILE_OPENED)
return return
} }
if (fileOpenMode < 1) { if (fileOpenMode < 1) {
statusCode = TestDiskDrive.STATE_CODE_OPERATION_NOT_PERMITTED statusCode.set(TestDiskDrive.STATE_CODE_OPERATION_NOT_PERMITTED)
return return
} }
try { try {
val status = file.mkdir() val status = file.mkdir()
statusCode = if (status) 0 else 1 statusCode.set(if (status) 0 else 1)
if (status) hasChanges.getAndSet(true) if (status) hasChanges.getAndSet(true)
} }
catch (e: SecurityException) { catch (e: SecurityException) {
statusCode = TestDiskDrive.STATE_CODE_SYSTEM_SECURITY_ERROR statusCode.set(TestDiskDrive.STATE_CODE_SYSTEM_SECURITY_ERROR)
} }
} }
else if (inputString.startsWith("MKFILE")) { else if (inputString.startsWith("MKFILE")) {
if (!fileOpen) { if (!fileOpen) {
statusCode = TestDiskDrive.STATE_CODE_NO_FILE_OPENED statusCode.set(TestDiskDrive.STATE_CODE_NO_FILE_OPENED)
return return
} }
if (fileOpenMode < 1) { if (fileOpenMode < 1) {
statusCode = TestDiskDrive.STATE_CODE_OPERATION_NOT_PERMITTED statusCode.set(TestDiskDrive.STATE_CODE_OPERATION_NOT_PERMITTED)
return return
} }
try { try {
val f1 = file.createNewFile() val f1 = file.createNewFile()
statusCode = if (f1) TestDiskDrive.STATE_CODE_STANDBY else TestDiskDrive.STATE_CODE_OPERATION_FAILED statusCode.set(if (f1) TestDiskDrive.STATE_CODE_STANDBY else TestDiskDrive.STATE_CODE_OPERATION_FAILED)
if (f1) hasChanges.getAndSet(true) if (f1) hasChanges.getAndSet(true)
return return
} }
catch (e: IOException) { catch (e: IOException) {
statusCode = TestDiskDrive.STATE_CODE_SYSTEM_IO_ERROR statusCode.set(TestDiskDrive.STATE_CODE_SYSTEM_IO_ERROR)
} }
catch (e1: SecurityException) { catch (e1: SecurityException) {
statusCode = TestDiskDrive.STATE_CODE_SYSTEM_SECURITY_ERROR statusCode.set(TestDiskDrive.STATE_CODE_SYSTEM_SECURITY_ERROR)
} }
} }
else if (inputString.startsWith("TOUCH")) { else if (inputString.startsWith("TOUCH")) {
if (!fileOpen) { if (!fileOpen) {
statusCode = TestDiskDrive.STATE_CODE_NO_FILE_OPENED statusCode.set(TestDiskDrive.STATE_CODE_NO_FILE_OPENED)
return return
} }
if (fileOpenMode < 1) { if (fileOpenMode < 1) {
statusCode = TestDiskDrive.STATE_CODE_OPERATION_NOT_PERMITTED statusCode.set(TestDiskDrive.STATE_CODE_OPERATION_NOT_PERMITTED)
return return
} }
try { try {
val f1 = file.setLastModified(vm.worldInterface.currentTimeInMills()) val f1 = file.setLastModified(vm.worldInterface.currentTimeInMills())
statusCode = if (f1) TestDiskDrive.STATE_CODE_STANDBY else TestDiskDrive.STATE_CODE_OPERATION_FAILED statusCode.set(if (f1) TestDiskDrive.STATE_CODE_STANDBY else TestDiskDrive.STATE_CODE_OPERATION_FAILED)
if (f1) hasChanges.getAndSet(true) if (f1) hasChanges.getAndSet(true)
return return
} }
catch (e: IOException) { catch (e: IOException) {
statusCode = TestDiskDrive.STATE_CODE_SYSTEM_IO_ERROR statusCode.set(TestDiskDrive.STATE_CODE_SYSTEM_IO_ERROR)
} }
catch (e1: SecurityException) { catch (e1: SecurityException) {
statusCode = TestDiskDrive.STATE_CODE_SYSTEM_SECURITY_ERROR statusCode.set(TestDiskDrive.STATE_CODE_SYSTEM_SECURITY_ERROR)
} }
} }
else if (inputString.startsWith("WRITE")) { else if (inputString.startsWith("WRITE")) {
if (!fileOpen) { if (!fileOpen) {
statusCode = TestDiskDrive.STATE_CODE_NO_FILE_OPENED statusCode.set(TestDiskDrive.STATE_CODE_NO_FILE_OPENED)
return return
} }
if (fileOpenMode < 0) { if (fileOpenMode < 0) {
statusCode = TestDiskDrive.STATE_CODE_OPERATION_NOT_PERMITTED statusCode.set(TestDiskDrive.STATE_CODE_OPERATION_NOT_PERMITTED)
return return
} }
if (fileOpenMode == 1) { writeMode = true; appendMode = false } if (fileOpenMode == 1) { writeMode = true; appendMode = false }
@@ -412,10 +412,10 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
writeModeLength = inputString.substring(5, inputString.length).toInt() writeModeLength = inputString.substring(5, inputString.length).toInt()
writeBuffer = ByteArray(writeModeLength) writeBuffer = ByteArray(writeModeLength)
writeBufferUsage = 0 writeBufferUsage = 0
statusCode = TestDiskDrive.STATE_CODE_STANDBY statusCode.set(TestDiskDrive.STATE_CODE_STANDBY)
} }
else else
statusCode = TestDiskDrive.STATE_CODE_ILLEGAL_COMMAND statusCode.set(TestDiskDrive.STATE_CODE_ILLEGAL_COMMAND)
} }
} }

View File

@@ -29,7 +29,7 @@ class WorldRadar(pngfile: FileHandle) : BlockTransferInterface(false, true) {
private val STONE_OUT = 7.toByte() private val STONE_OUT = 7.toByte()
init { init {
statusCode = TestDiskDrive.STATE_CODE_STANDBY statusCode.set(TestDiskDrive.STATE_CODE_STANDBY)
val worldTex = Pixmap(pngfile) val worldTex = Pixmap(pngfile)
for (y in 0 until worldTex.height) { for (x in 0 until worldTex.width) { for (y in 0 until worldTex.height) { for (x in 0 until worldTex.width) {
@@ -129,11 +129,11 @@ class WorldRadar(pngfile: FileHandle) : BlockTransferInterface(false, true) {
oldCmdbuf = cmdbuf oldCmdbuf = cmdbuf
statusCode = TestDiskDrive.STATE_CODE_STANDBY statusCode.set(TestDiskDrive.STATE_CODE_STANDBY)
} }
else { else {
resetBuf() resetBuf()
statusCode = TestDiskDrive.STATE_CODE_ILLEGAL_COMMAND statusCode.set(TestDiskDrive.STATE_CODE_ILLEGAL_COMMAND)
} }
} }
} }