mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-06-11 23:34:04 +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!")
|
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 copyFiles(destDrive) {
|
||||||
function dir(path) {
|
function dir(path) {
|
||||||
@@ -36,4 +80,15 @@ function copyFiles(destDrive) {
|
|||||||
com.sendMessage(port, "FLUSH");com.sendMessage(port, "CLOSE")
|
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
|
88 RW: Rom mapping
|
||||||
|
|
||||||
89 RO: BMS flags
|
89 RW: BMS flags
|
||||||
0b b000 00ca
|
0b P000 b0ca
|
||||||
a: 1 if charging (accepting power from the AC adapter)
|
a: 1 if charging (accepting power from the AC adapter)
|
||||||
c: 1 if battery is detected
|
c: 1 if battery is detected
|
||||||
b: 1 if the device is battery-operated
|
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,
|
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%
|
90 RO: BMS calculated battery percentage where 255 is 100%
|
||||||
91 RO: BMS battery voltage multiplied by 10 (127 = "12.7 V")
|
91 RO: BMS battery voltage multiplied by 10 (127 = "12.7 V")
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ object VMSetupBroker {
|
|||||||
vm.getPrintStream = { gpu.getPrintStream() }
|
vm.getPrintStream = { gpu.getPrintStream() }
|
||||||
vm.getErrorStream = { gpu.getErrorStream() }
|
vm.getErrorStream = { gpu.getErrorStream() }
|
||||||
vm.getInputStream = { gpu.getInputStream() }
|
vm.getInputStream = { gpu.getInputStream() }
|
||||||
|
vm.poke(-90L, 0)
|
||||||
|
|
||||||
vmRunners[vm.id] = VMRunnerFactory(vm.assetsDir, vm, "js")
|
vmRunners[vm.id] = VMRunnerFactory(vm.assetsDir, vm, "js")
|
||||||
coroutineJobs[vm.id] = GlobalScope.launch { vmRunners[vm.id]?.executeCommand(vm.roms[0]!!.readAll()) }
|
coroutineJobs[vm.id] = GlobalScope.launch { vmRunners[vm.id]?.executeCommand(vm.roms[0]!!.readAll()) }
|
||||||
@@ -56,6 +57,7 @@ object VMSetupBroker {
|
|||||||
vm.getPrintStream = { TODO() }
|
vm.getPrintStream = { TODO() }
|
||||||
vm.getErrorStream = { TODO() }
|
vm.getErrorStream = { TODO() }
|
||||||
vm.getInputStream = { TODO() }
|
vm.getInputStream = { TODO() }
|
||||||
|
vm.poke(-90L, -128)
|
||||||
|
|
||||||
vmRunners[vm.id]?.close()
|
vmRunners[vm.id]?.close()
|
||||||
coroutineJobs[vm.id]?.cancel("VM kill command received")
|
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.g2d.TextureRegion
|
||||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||||
import com.badlogic.gdx.math.Matrix4
|
import com.badlogic.gdx.math.Matrix4
|
||||||
|
import com.badlogic.gdx.utils.GdxRuntimeException
|
||||||
import net.torvald.UnsafeHelper
|
import net.torvald.UnsafeHelper
|
||||||
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.toUint
|
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.toUint
|
||||||
import net.torvald.tsvm.FBM
|
import net.torvald.tsvm.FBM
|
||||||
@@ -937,9 +938,9 @@ open class GraphicsAdapter(private val assetsRoot: String, val vm: VM, val confi
|
|||||||
|
|
||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
//testTex.dispose()
|
//testTex.dispose()
|
||||||
framebuffer.destroy()
|
try { framebuffer.destroy() } catch (_: GdxRuntimeException) {}
|
||||||
framebuffer2?.destroy()
|
try { framebuffer2?.destroy() } catch (_: GdxRuntimeException) {}
|
||||||
framebufferOut.dispose()
|
try { framebufferOut.dispose() } catch (_: GdxRuntimeException) {}
|
||||||
rendertex.dispose()
|
rendertex.dispose()
|
||||||
textArea.destroy()
|
textArea.destroy()
|
||||||
textForePixmap.dispose()
|
textForePixmap.dispose()
|
||||||
@@ -951,8 +952,8 @@ open class GraphicsAdapter(private val assetsRoot: String, val vm: VM, val confi
|
|||||||
outFBOs.forEach { it.dispose() }
|
outFBOs.forEach { it.dispose() }
|
||||||
outFBObatch.dispose()
|
outFBObatch.dispose()
|
||||||
|
|
||||||
try { textForeTex.dispose() } catch (_: Throwable) {}
|
try { textForeTex.dispose() } catch (_: GdxRuntimeException) {}
|
||||||
try { textBackTex.dispose() } catch (_: Throwable) {}
|
try { textBackTex.dispose() } catch (_: GdxRuntimeException) {}
|
||||||
|
|
||||||
chrrom0.dispose()
|
chrrom0.dispose()
|
||||||
chrrom.dispose()
|
chrrom.dispose()
|
||||||
|
|||||||
@@ -42,6 +42,11 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor {
|
|||||||
|
|
||||||
private val keyEventBuffers = ByteArray(8)
|
private val keyEventBuffers = ByteArray(8)
|
||||||
|
|
||||||
|
private var acpiShutoff = true
|
||||||
|
private var bmsIsCharging = false
|
||||||
|
private var bmsHasBattery = false
|
||||||
|
private var bmsIsBatteryOperated = false
|
||||||
|
|
||||||
init {
|
init {
|
||||||
//blockTransferPorts[1].attachDevice(TestFunctionGenerator())
|
//blockTransferPorts[1].attachDevice(TestFunctionGenerator())
|
||||||
//blockTransferPorts[0].attachDevice(TestDiskDrive(vm, 0, File("assets")))
|
//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? {
|
override fun peek(addr: Long): Byte? {
|
||||||
return mmio_read(addr)
|
return mmio_read(addr)
|
||||||
}
|
}
|
||||||
@@ -105,6 +111,9 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor {
|
|||||||
|
|
||||||
88L -> vm.romMapping.toByte()
|
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]
|
in 1024..2047 -> peripheralFast[addr - 1024]
|
||||||
|
|
||||||
4076L -> blockTransferPorts[0].statusCode.toByte()
|
4076L -> blockTransferPorts[0].statusCode.toByte()
|
||||||
@@ -164,6 +173,7 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
88L -> vm.romMapping = bi
|
88L -> vm.romMapping = bi
|
||||||
|
89L -> { acpiShutoff = byte.and(-128).isNonZero() }
|
||||||
|
|
||||||
in 1024..2047 -> peripheralFast[addr - 1024] = byte
|
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}"))
|
recipient?.writeout(TestDiskDrive.composePositiveAns("USED${DOM.usedBytes}/TOTAL${DOM.capacity}"))
|
||||||
statusCode.set(TestDiskDrive.STATE_CODE_STANDBY)
|
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
|
else
|
||||||
statusCode.set(TestDiskDrive.STATE_CODE_ILLEGAL_COMMAND)
|
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.Color
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import net.torvald.tsvm.VMEmuExecutableWrapper.Companion.FONT
|
import net.torvald.tsvm.VMEmuExecutableWrapper.Companion.FONT
|
||||||
|
import kotlin.experimental.and
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2022-10-25.
|
* 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_PLAY = "\u00D2\u00D3"
|
||||||
private val STR_STOP = "\u00D0\u00D1"
|
private val STR_STOP = "\u00D0\u00D1"
|
||||||
|
private val STR_POWER = "\u00D4\u00D5"
|
||||||
|
|
||||||
override fun render(batch: SpriteBatch) {
|
override fun render(batch: SpriteBatch) {
|
||||||
batch.inUse {
|
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)
|
FONT.draw(batch, STR_STOP, 377f, 382f)
|
||||||
batch.setColourBy { theVM?.isRunning == true }
|
batch.setColourBy { theVM?.isRunning == true }
|
||||||
FONT.draw(batch, STR_PLAY, 398f, 382f)
|
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