dos kernel wip

This commit is contained in:
minjaesong
2020-10-29 11:52:31 +09:00
parent 5167bf1034
commit 219bc641cf
10 changed files with 105 additions and 79 deletions

View File

@@ -1,6 +1,10 @@
println("TERRAN Megatrends inc.");
//println("Main RAM:"+(system.maxmem() >> 10)+" KBytes");
///////////////////////////////////////////////////////////////////////////////
// Perform memtest
let memptr = 0;
const memtestptn = [
// Overclockers will LOVE this!
@@ -62,4 +66,20 @@ catch (e) {
}
}
///////////////////////////////////////////////////////////////////////////////
// probe bootable device
var _BIOS = {};
// Syntax: [Port, Drive-number]
// Port #0-3: Serial port 1-4
// #4+ : Left for future extension
// Drive-number always starts at 1
_BIOS.FIRST_BOOTABLE_PORT = [0,1]; // ah screw it
Object.freeze(_BIOS);
///////////////////////////////////////////////////////////////////////////////
con.move(4,1);

View File

@@ -1,36 +1 @@
function getStatusMessage(portNo) {
return com.sendMessageGetBytes(portNo, "DEVSTU"+String.fromCharCode(0x17));
}
let ba = com.sendMessageGetBytes(0, "DEVNAM"+String.fromCharCode(0x17));
serial.println(ba);
ba = com.pullMessage(0)
serial.print(ba);
serial.println("# END OF MSG");
ba = com.sendMessageGetBytes(1, "DEVNAM"+String.fromCharCode(0x17));
serial.println(ba);
serial.println(getStatusMessage(1));
ba = com.sendMessageGetBytes(1, "LIST");
ba = com.pullMessage(1);
println(ba);
serial.println(getStatusMessage(1));
com.sendMessage(1, "OPENR\"fsh.js\"");
println("Status code: "+com.getStatusCode(1));
com.sendMessage(1, "READ");
println("Status code: "+com.getStatusCode(1));
let source = com.pullMessage(1);
println(source);
eval(source);
serial.println("k bye")
println("Hello, world!");

55
assets/tvdos/TVDOS.SYS Normal file
View File

@@ -0,0 +1,55 @@
// Boot script
var _TVDOS = {};
_TVDOS.DRIVES = {}; // Object where key-value pair is <drive-letter> : [serial-port, drive-number]
// actually figure out the drive letter association
// Drive A is always the device we're currently on
_TVDOS.DRIVES["A"] = _BIOS.FIRST_BOOTABLE_PORT;
Object.freeze(_TVDOS);
///////////////////////////////////////////////////////////////////////////////
var filesystem = {};
filesystem._toPorts = function(driveLetter) {
let port = _TVDOS.DRIVES[driveLetter.toUpperCase()];
if (port === undefined) {
throw Error("Drive letter '" + driveLetter.toUpperCase() + "' does not exist");
}
return port
};
filesystem._close = function(portNo) {
com.sendMessage(portNo, "CLOSE");
};
filesystem._flush = function(portNo) {
com.sendMessage(portNo, "FLUSH");
};
// @return true if operation committed successfully, false otherwise; throws error
// if unknown mode or invalid drive letter was given
filesystem.open = function(driveLetter, path, operationMode) {
let port = filesystem._toPorts(driveLetter);
filesystem._flush(port[0]); filesystem._close(port[0]);
let mode = operationMode.toUpperCase();
if (mode != "R" && mode != "W" && mode != "A") {
throw Error("Unknown file opening mode: " + mode);
}
com.sendMessage(port[0], "OPEN"+mode+'"'+path+'",'+port[1]);
let response = com.getStatusCode();
return (response == 0);
};
// @return the entire contents of the file in String
filesystem.readAll = function() {
let port = filesystem._toPorts(driveLetter);
com.sendMessage(port[0], "READ");
let response = com.getStatusCode();
if (response < 0 || response >= 128) {
let status = com.getDeviceStatus(port[0]);
throw Error("Reading a file failed with "+status.code+": "+status.message);
}
return com.pullMessage(port[0]);
};
Object.freeze(filesystem);

View File

@@ -1,5 +1,5 @@
const DOS_VERSION = "1.0";
const PROMPT_TEXT = ">";
let PROMPT_TEXT = ">";
let CURRENT_DRIVE = "A";
let shell_pwd = [""];

View File

@@ -55,9 +55,9 @@ Returns: none
Description: reads status of the device, if applicable
Returns:
0x06 <status code> <0x1F> <message string> 0x17
0x15 <status code> <0x1F> <message string> 0x17
Status Code is single byte number. Also see section 1.0
<status code> <0x1F> <message string> 0x17
Status Code is single byte number, negative numbers (or >= 128) is used for negative response by convention.
Also see section 1.0
2. Device-specific commands
@@ -69,7 +69,8 @@ Status Code is single byte number. Also see section 1.0
2.1.0 NOTE
comma-followed-by-drive-number can be omitted; drive number 1 will be substituted
- comma-followed-by-drive-number can be omitted; drive number 1 will be substituted
- drive number always starts at 1
2.1.1 File Control
@@ -108,23 +109,24 @@ Description: closes any file that is open.
LOAD"<path to file>",<drive number>
Description: loads an executable file for running. Will throw an error if the file is not executable.
Description: loads a file onto the main memory. The pointer to the file will be sent back to the host device.
CHTYPE,<file type>,<drive number>
Description: changes the file's file type (or its extension)
Description: changes the open file's file type (or its extension)
CHDIR"<path>"
LIST
Description: changes the working directory of the filesystem to given path. Disk with non-hierarchical filesystem should
ignore this command.
Description: lists contents of the open (with OPENR) directory in READABLE FORMAT
(no 0x17 at the end, terminates string with zero)
When a file is opened instead of a directory, its filename should be printed
Raw filesystem (e.g. EPROM) should return first 4096 bytes of its contents.
LIST,<drive number>
LIST"<path>",<drive number>
LISTFILES
Description: lists contents of the given directory in READABLE FORMAT (no 0x17 at the end, terminates string with zero)
If no path is given, current working directory will be used instead. Non-hierarchical system should ignore
PATH argument, and raw filesystem (e.g. EPROM) should return first 4096 bytes of its contents.
Description: same as the LIST, but in machine readable format, which follows the following format:
<file/dir type> <filename> [<0x1E for separator> <file/dir type> <filename> ...] <0x17>
file/dir type: 0x11 for file, 0x12 for directory
USAGE,<drive number>

View File

@@ -80,7 +80,6 @@ object SerialHelper {
fun getDeviceStatus(vm: VM, portNo: Int): DeviceStatus {
val msgStr = sendMessageGetBytes(vm, portNo, "DEVSTU$END_OF_SEND_BLOCK".toByteArray(VM.CHARSET))
return DeviceStatus(
msgStr[0] == 0x06.toByte(),
msgStr[1].toUint(),
msgStr.sliceArray(3 until msgStr.size - 1).toString(VM.CHARSET)
)
@@ -130,7 +129,7 @@ object SerialHelper {
private fun Boolean.toInt() = if (this) 1 else 0
data class DeviceStatus(val isError: Boolean, val code: Int, val message: String)
data class DeviceStatus(val code: Int, val message: String)
}
class SerialHelperDelegate(val vm: VM) {
@@ -138,7 +137,8 @@ class SerialHelperDelegate(val vm: VM) {
fun pullMessage(portNo: Int) = SerialHelper.pullMessage(vm, portNo).toString(VM.CHARSET)
fun sendMessageGetBytes(portNo: Int, message: String) = SerialHelper.sendMessageGetBytes(vm, portNo, message.toByteArray(VM.CHARSET)).toString(VM.CHARSET)
fun fetchResponse(portNo: Int) = SerialHelper.fetchResponse(vm, portNo).toString(VM.CHARSET)
fun getDeviceStatus(portNo: Int) = SerialHelper.getDeviceStatus(vm, portNo)
fun waitUntilReady(portNo: Int) = SerialHelper.waitUntilReady(vm, portNo)
fun getStatusCode(portNo: Int) = SerialHelper.getStatusCode(vm, portNo)
/** @return Object where { code: <Int>, message: <String> } */
fun getDeviceStatus(portNo: Int) = SerialHelper.getDeviceStatus(vm, portNo)
}

View File

@@ -65,6 +65,10 @@ class VMGUI(val appConfig: LwjglApplicationConfiguration) : ApplicationAdapter()
val tvgl = fr2.readText()
fr2.close()
val fr3 = FileReader("./assets/tvdos/TVDOS.SYS")
val tvknl = fr3.readText()
fr3.close()
//val fr = FileReader("./assets/tvdos/command.js")
//val fr = FileReader("./assets/zippytest.js")
@@ -77,7 +81,7 @@ class VMGUI(val appConfig: LwjglApplicationConfiguration) : ApplicationAdapter()
vmRunner = VMRunnerFactory(vm, "js")
coroutineJob = GlobalScope.launch {
vmRunner.evalGlobal(bios + "\n" + tvgl)
vmRunner.evalGlobal("$bios\n$tvknl\n$tvgl")
vmRunner.executeCommand(prg)
}
}

View File

@@ -38,8 +38,8 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor {
private val keyEventBuffers = ByteArray(8)
init {
blockTransferPorts[0].attachDevice(TestFunctionGenerator())
blockTransferPorts[1].attachDevice(TestDiskDrive(0))
//blockTransferPorts[0].attachDevice(TestFunctionGenerator())
blockTransferPorts[0].attachDevice(TestDiskDrive(0))
}
private fun composeBlockTransferStatus(portno: Int): Int {

View File

@@ -31,19 +31,6 @@ class TestDiskDrive(private val driveNum: Int) : BlockTransferInterface(false, t
fun composePositiveAns(vararg msg: String): ByteArray {
val sb = ArrayList<Byte>()
sb.add(GOOD_NEWS)
sb.addAll(msg[0].toByteArray().toTypedArray())
for (k in 1 until msg.size) {
sb.add(UNIT_SEP)
sb.addAll(msg[k].toByteArray().toTypedArray())
}
sb.add(END_OF_SEND_BLOCK)
return sb.toByteArray()
}
fun composeNegativeAns(vararg msg: String): ByteArray {
val sb = ArrayList<Byte>()
sb.add(BAD_NEWS)
sb.addAll(msg[0].toByteArray().toTypedArray())
for (k in 1 until msg.size) {
sb.add(UNIT_SEP)
@@ -130,14 +117,8 @@ class TestDiskDrive(private val driveNum: Int) : BlockTransferInterface(false, t
writeMode = false
writeModeLength = -1
}
else if (inputString.startsWith("DEVSTU\u0017")) {
if (statusCode < 128) {
recipient?.writeout(composePositiveAns("${statusCode.toChar()}", errorMsgs[statusCode]))
}
else {
recipient?.writeout(composeNegativeAns("${statusCode.toChar()}", errorMsgs[statusCode]))
}
}
else if (inputString.startsWith("DEVSTU\u0017"))
recipient?.writeout(composePositiveAns("${statusCode.toChar()}", errorMsgs[statusCode]))
else if (inputString.startsWith("DEVTYP\u0017"))
recipient?.writeout(composePositiveAns("STOR"))
else if (inputString.startsWith("DEVNAM\u0017"))

View File

@@ -90,7 +90,6 @@ Nunc mollis nibh vitae sapien consequat, ut vestibulum sem pharetra. Aliquam iac
fun composeSerialAns(vararg msg: String): ByteArray {
val sb = ArrayList<Byte>()
sb.add(0x06) // always positive ans
sb.addAll(msg[0].toByteArray().toTypedArray())
for (k in 1 until msg.lastIndex) {
sb.add(0x1F)