cpu halted flag on vm's mmio

This commit is contained in:
minjaesong
2022-12-28 04:54:14 +09:00
parent d619106a57
commit 3282faf9e6
12 changed files with 116 additions and 14 deletions

View File

@@ -1 +1 @@
let p=_BIOS.FIRST_BOOTABLE_PORT;com.sendMessage(p[0],"DEVRST\x17");com.sendMessage(p[0],'OPENR"tvdos/TVDOS.SYS",'+p[1]);let r=com.getStatusCode(p[0]);if(0==r)if(com.sendMessage(p[0],"READ"),r=com.getStatusCode(p[0]),0==r){let g=com.pullMessage(p[0]);eval(g)}else println("I/O Error");else println("TVDOS.SYS not found");println("Shutting down...");println("It is now safe to turn off the power");
let p=_BIOS.FIRST_BOOTABLE_PORT;com.sendMessage(p[0],"DEVRST\x17");com.sendMessage(p[0],'OPENR"tvdos/TVDOS.SYS",'+p[1]);let r=com.getStatusCode(p[0]);if(0==r)if(com.sendMessage(p[0],"READ"),r=com.getStatusCode(p[0]),0==r){let g=com.pullMessage(p[0]);eval(g)}else println("I/O Error");else println("TVDOS.SYS not found");println("Shutting down...");println("It is now safe to turn off the power");sys.poke(-90,128)

View File

@@ -1 +1 @@
let p=_BIOS.FIRST_BOOTABLE_PORT;com.sendMessage(p[0],"DEVRST\x17");com.sendMessage(p[0],'OPENR"tvdos/TVDOS.SYS",'+p[1]);let r=com.getStatusCode(p[0]);if(0==r)if(com.sendMessage(p[0],"READ"),r=com.getStatusCode(p[0]),0==r){let g=com.pullMessage(p[0]);eval(g)}else println("I/O Error");else println("TVDOS.SYS not found");println("Shutting down...");println("It is now safe to turn off the power");
let p=_BIOS.FIRST_BOOTABLE_PORT;com.sendMessage(p[0],"DEVRST\x17");com.sendMessage(p[0],'OPENR"tvdos/TVDOS.SYS",'+p[1]);let r=com.getStatusCode(p[0]);if(0==r)if(com.sendMessage(p[0],"READ"),r=com.getStatusCode(p[0]),0==r){let g=com.pullMessage(p[0]);eval(g)}else println("I/O Error");else println("TVDOS.SYS not found");println("Shutting down...");println("It is now safe to turn off the power");sys.poke(-90,128)

View File

@@ -1 +1 @@
let p=_BIOS.FIRST_BOOTABLE_PORT;com.sendMessage(p[0],"DEVRST\x17");com.sendMessage(p[0],'OPENR"tvdos/TVDOS.SYS",'+p[1]);let r=com.getStatusCode(p[0]);if(0==r)if(com.sendMessage(p[0],"READ"),r=com.getStatusCode(p[0]),0==r){let g=com.pullMessage(p[0]);eval(g)}else println("The Installation Medium seems to be damaged. Please contact your reseller or system administrators.");else println("TVDOS.SYS not found");println();println("Remove the Installation Medium, close the tray (if any), then shut off and restart the computer to finish the installation.");
let p=_BIOS.FIRST_BOOTABLE_PORT;com.sendMessage(p[0],"DEVRST\x17");com.sendMessage(p[0],'OPENR"tvdos/TVDOS.SYS",'+p[1]);let r=com.getStatusCode(p[0]);if(0==r)if(com.sendMessage(p[0],"READ"),r=com.getStatusCode(p[0]),0==r){let g=com.pullMessage(p[0]);eval(g)}else println("The Installation Medium seems to be damaged. Please contact your reseller or system administrators.");else println("TVDOS.SYS not found");println();println("Remove the Installation Medium, close the tray (if any), then shut off and restart the computer to finish the installation.");sys.poke(-90,128)

View File

@@ -1 +1 @@
let p=_BIOS.FIRST_BOOTABLE_PORT;com.sendMessage(p[0],"DEVRST\x17");com.sendMessage(p[0],'OPENR"tvdos/TVDOS.SYS",'+p[1]);let r=com.getStatusCode(p[0]);if(0==r)if(com.sendMessage(p[0],"READ"),r=com.getStatusCode(p[0]),0==r){let g=com.pullMessage(p[0]);eval(g)}else println("I/O Error");else println("TVDOS.SYS not found");println("Shutting down...");println("It is now safe to turn off the power");
let p=_BIOS.FIRST_BOOTABLE_PORT;com.sendMessage(p[0],"DEVRST\x17");com.sendMessage(p[0],'OPENR"tvdos/TVDOS.SYS",'+p[1]);let r=com.getStatusCode(p[0]);if(0==r)if(com.sendMessage(p[0],"READ"),r=com.getStatusCode(p[0]),0==r){let g=com.pullMessage(p[0]);eval(g)}else println("I/O Error");else println("TVDOS.SYS not found");println("Shutting down...");println("It is now safe to turn off the power");sys.poke(-90,128)

View File

@@ -1,5 +1,49 @@
println("let's install!")
/* procedure:
CANCELLED_BY_USER :=
println("Installation of TVDOS was cancelled by the user.")
exit with errorlevel 1
1. show the list of installable drives. Read-only drives are considered not installable
1.1 if there is at least one installable drives, show the following message:
select drive to install [B,C,D]:
1.2 else, show the following message:
No suitable drives were detected for installing TVDOS. The setup program will exit. (exit with errorlevel 2)
2. check if the drive has boot sector. if there is, show message:
This drive appears to be bootable, which means there might be other operation system on this drive.
Proceed anyway? [Y/N]:
2.1. if read().trim().toLowercase() is not "y", do CANCELLED_BY_USER
3. show the following message:
In order to install TVDOS to the drive ${destDrive}, the drive must be wiped clean first.
THIS PROCESS WILL IRREVERSIBLY DESTROY ALL THE DATA IN THE DRIVE ${destDrive}!
Type "yes, I consent" to proceed, or type any other text to cancel the installation process:
3.1. if read().trim().toLowercase() is not "yes, i consent" or "yes i consent", do CANCELLED_BY_USER
4. show the following message:
Enter the new name for the drive that TVDOS will be installed:
5. show the following message:
The destination disk will be wiped now. Do not turn off the power...
6. formatDrive(destDrive, newName, driveNum)
7. show following message:
TVDOS will be installed into the drive ${destDrive}...
8. copyFiles(destDrive)
9. show following message
TVDOS is successfully installed. You may continue using the Live Boot environment.
To boot from the newly-installed TVDOS, turn off the computer, remove the installation medium, then start the
computer again. (exit with errorlevel 0)
*/
function copyFiles(destDrive) {
function dir(path) {
@@ -36,4 +80,15 @@ function copyFiles(destDrive) {
com.sendMessage(port, "FLUSH");com.sendMessage(port, "CLOSE")
}
function formatDrive(destDrive, newName, driveNum) {
let [port, poru] = _TVDOS.DRV.FS.SERIAL._toPorts(destDrive)[0]
com.sendMessage(port, "FLUSH");com.sendMessage(port, "CLOSE")
com.sendMessage(port, `TEVDDISCARDDRIVE"${newName}",${poru}`)
let status = com.getStatusCode(port[0])
if (status != 0)
throw Error("Formatting the disk failed: "+status)
}

View File

@@ -88,14 +88,18 @@ MMIO
88 RW: Rom mapping
89 RO: BMS flags
0b b000 00ca
89 RW: BMS flags
0b P000 b0ca
a: 1 if charging (accepting power from the AC adapter)
c: 1 if battery is detected
b: 1 if the device is battery-operated
P: 1 if CPU halted (so that the "smart" power supply can shut itself down)
note: only the high nybbles are writable!
if the device is battery-operated but currently running off of an AC adapter and there is no battery inserted,
the flag would be 1000 0001
the flag would be 0000 1001
90 RO: BMS calculated battery percentage where 255 is 100%
91 RO: BMS battery voltage multiplied by 10 (127 = "12.7 V")

View File

@@ -34,6 +34,7 @@ object VMSetupBroker {
vm.getPrintStream = { gpu.getPrintStream() }
vm.getErrorStream = { gpu.getErrorStream() }
vm.getInputStream = { gpu.getInputStream() }
vm.poke(-90L, 0)
vmRunners[vm.id] = VMRunnerFactory(vm.assetsDir, vm, "js")
coroutineJobs[vm.id] = GlobalScope.launch { vmRunners[vm.id]?.executeCommand(vm.roms[0]!!.readAll()) }
@@ -56,6 +57,7 @@ object VMSetupBroker {
vm.getPrintStream = { TODO() }
vm.getErrorStream = { TODO() }
vm.getInputStream = { TODO() }
vm.poke(-90L, -128)
vmRunners[vm.id]?.close()
coroutineJobs[vm.id]?.cancel("VM kill command received")

View File

@@ -7,6 +7,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.badlogic.gdx.graphics.glutils.FrameBuffer
import com.badlogic.gdx.math.Matrix4
import com.badlogic.gdx.utils.GdxRuntimeException
import net.torvald.UnsafeHelper
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.toUint
import net.torvald.tsvm.FBM
@@ -937,9 +938,9 @@ open class GraphicsAdapter(private val assetsRoot: String, val vm: VM, val confi
override fun dispose() {
//testTex.dispose()
framebuffer.destroy()
framebuffer2?.destroy()
framebufferOut.dispose()
try { framebuffer.destroy() } catch (_: GdxRuntimeException) {}
try { framebuffer2?.destroy() } catch (_: GdxRuntimeException) {}
try { framebufferOut.dispose() } catch (_: GdxRuntimeException) {}
rendertex.dispose()
textArea.destroy()
textForePixmap.dispose()
@@ -951,8 +952,8 @@ open class GraphicsAdapter(private val assetsRoot: String, val vm: VM, val confi
outFBOs.forEach { it.dispose() }
outFBObatch.dispose()
try { textForeTex.dispose() } catch (_: Throwable) {}
try { textBackTex.dispose() } catch (_: Throwable) {}
try { textForeTex.dispose() } catch (_: GdxRuntimeException) {}
try { textBackTex.dispose() } catch (_: GdxRuntimeException) {}
chrrom0.dispose()
chrrom.dispose()

View File

@@ -42,6 +42,11 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor {
private val keyEventBuffers = ByteArray(8)
private var acpiShutoff = true
private var bmsIsCharging = false
private var bmsHasBattery = false
private var bmsIsBatteryOperated = false
init {
//blockTransferPorts[1].attachDevice(TestFunctionGenerator())
//blockTransferPorts[0].attachDevice(TestDiskDrive(vm, 0, File("assets")))
@@ -76,6 +81,7 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor {
}
}
override fun peek(addr: Long): Byte? {
return mmio_read(addr)
}
@@ -105,6 +111,9 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor {
88L -> vm.romMapping.toByte()
89L -> ((acpiShutoff.toInt() shl 7) or (bmsIsBatteryOperated.toInt() shl 3) or (bmsHasBattery.toInt() shl 1)
or bmsIsCharging.toInt()).toByte()
in 1024..2047 -> peripheralFast[addr - 1024]
4076L -> blockTransferPorts[0].statusCode.toByte()
@@ -164,6 +173,7 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor {
}
88L -> vm.romMapping = bi
89L -> { acpiShutoff = byte.and(-128).isNonZero() }
in 1024..2047 -> peripheralFast[addr - 1024] = byte

View File

@@ -464,6 +464,33 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
recipient?.writeout(TestDiskDrive.composePositiveAns("USED${DOM.usedBytes}/TOTAL${DOM.capacity}"))
statusCode.set(TestDiskDrive.STATE_CODE_STANDBY)
}
else if (inputString.startsWith("TEVDDISCARDDRIVE\"")) {
// the actual capacity of the floppy must be determined when the floppy gameitem was created
if (DOM.isReadOnly) {
printdbg("! disk is read-only")
statusCode.set(TestDiskDrive.STATE_CODE_READ_ONLY)
return
}
var commaIndex = inputString.lastIndex
while (commaIndex > 6) {
if (inputString[commaIndex] == ',') break; commaIndex -= 1
}
// sanity check if path is actually enclosed with double-quote
if (commaIndex != 6 && inputString[commaIndex - 1] != '"') {
statusCode.set(TestDiskDrive.STATE_CODE_ILLEGAL_COMMAND)
return
}
val newName = inputString.substring(6, if (commaIndex == 6) inputString.lastIndex else commaIndex - 1)
val driveNum =
if (commaIndex == 6) null else inputString.substring(commaIndex + 1, inputString.length).toInt()
// TODO driveNum is for disk drives that may have two or more slots built; for testing purposes we'll ignore it
DOM.entries.clear()
DOM.diskName = newName.toByteArray(VM.CHARSET)
}
else
statusCode.set(TestDiskDrive.STATE_CODE_ILLEGAL_COMMAND)
}

View File

@@ -5,6 +5,7 @@ import com.badlogic.gdx.Input.Buttons
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.tsvm.VMEmuExecutableWrapper.Companion.FONT
import kotlin.experimental.and
/**
* Created by minjaesong on 2022-10-25.
@@ -103,6 +104,7 @@ class ProfilesMenu(parent: VMEmuExecutable, x: Int, y: Int, w: Int, h: Int) : Em
private val STR_PLAY = "\u00D2\u00D3"
private val STR_STOP = "\u00D0\u00D1"
private val STR_POWER = "\u00D4\u00D5"
override fun render(batch: SpriteBatch) {
batch.inUse {
@@ -198,7 +200,8 @@ class ProfilesMenu(parent: VMEmuExecutable, x: Int, y: Int, w: Int, h: Int) : Em
FONT.draw(batch, STR_STOP, 377f, 382f)
batch.setColourBy { theVM?.isRunning == true }
FONT.draw(batch, STR_PLAY, 398f, 382f)
batch.setColourBy(Color.RED, Color.LIME) { (theVM?.peek(-90)?.and(-128) ?: 0.toByte()).toInt() != 0 }
FONT.draw(batch, STR_POWER, 419f, 382f)
}
}
}