mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-08 12:11:51 +09:00
cpu halted flag on vm's mmio
This commit is contained in:
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
|
||||
}
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user