basic: most basic and working INPUT

This commit is contained in:
minjaesong
2020-11-19 11:04:03 +09:00
parent 0d94951fc6
commit 5944db6096
6 changed files with 125 additions and 10 deletions

82
assets/bios/TBMBIOS.js Normal file
View File

@@ -0,0 +1,82 @@
println("(c) 125 TERRAN Business Machines inc.");
///////////////////////////////////////////////////////////////////////////////
// Perform memtest
let memptr = 0;
const memtestptn = [
[0x00,0xFF,0xAA,0x55 , 0x69,0x0F,0xA5,0x1E , 0xC7,0x71,0x8E,0xE3 , 0xCA,0xFE,0xBA,0xBE],
[0xFF,0xFF,0xFF,0xFF , 0xFF,0xFF,0xFF,0xFF , 0xFF,0xFF,0xFF,0xFF , 0xFF,0xFF,0xFF,0xFF]
];
con.move(2,1);
print("000 KB OK")
try {
while (memptr < (8 << 20)) {
// just print a number
con.move(2,1);
var memptrtext = ""+((memptr + 1) >> 10);
print((memptrtext < 10) ? "00"+memptrtext : (memptrtext < 100) ? "0"+memptrtext : memptrtext);
// perform memory test
for (var ptn = 0; ptn < memtestptn.length; ptn++) {
for (var bi = 0; bi < memtestptn[ptn].length; bi++) {
sys.poke(memptr + bi, memtestptn[ptn][bi]);
if (memtestptn[ptn][bi] != sys.peek(memptr + bi)) throw "Memory Error";
}
for (var bi = 0; bi < memtestptn[ptn].length; bi++) {
sys.poke(memptr + bi, 255 - memtestptn[ptn][bi]);
if (255 - memtestptn[ptn][bi] != sys.peek(memptr + bi)) throw "Memory Error";
}
}
memptr += memtestptn[0].length;
}
}
catch (e) {
if (e == "Memory Error") {
println(" "+e);
}
else {
println(" KB OK!");
}
}
///////////////////////////////////////////////////////////////////////////////
// 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);
///////////////////////////////////////////////////////////////////////////////
// load a bootsector using 'LOADBOOT'
let portNumber = 0;
let driveStatus = 0;
while (portNumber < 4) {
if (com.areYouThere(portNumber)) {
com.sendMessage(portNumber, "LOADBOOT");
driveStatus = com.getStatusCode(portNumber);
if (driveStatus == 0) break;
}
portNumber += 1;
}
if (portNumber < 4) {
eval(com.fetchResponse(portNumber).trimNull());
}
else {
sys.mapRom(1);
let response = eval("let _appStub=function(exec_args){"+sys.romReadAll()+"};_appStub;")();
if (response !== 0) println("No ROM BASIC system halted");
}

View File

@@ -114,6 +114,9 @@ fs.write = function(string) {
};
Object.freeze(fs);
// implement your own con object here
// requirements: reset_graphics(), getch(), curs_set(int), hitterminate(), resetkeybuf(), addch(int)
let getUsedMemSize = function() {
let varsMemSize = 0;
@@ -131,7 +134,6 @@ let getUsedMemSize = function() {
return varsMemSize + cmdbufMemFootPrint; // + array's dimsize * 8 + variables' sizeof literal + functions' expression length
}
let reLineNum = /^[0-9]+ /;
//var reFloat = /^([\-+]?[0-9]*[.][0-9]+[eE]*[\-+0-9]*[fF]*|[\-+]?[0-9]+[.eEfF][0-9+\-]*[fF]?)$/;
//var reDec = /^([\-+]?[0-9_]+)$/;
@@ -634,8 +636,10 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
"INPUT" : function(lnum, args) {
// just use tail-end arg as an input variable
let endArg = args.pop();
let arg = resolve(endArg);
if (arg === undefined) return undefined;
if (endArg === undefined) {
system.printerr("INPUT called with no arguments");
return undefined;
}
// print out prompt text
print("? ");
@@ -643,7 +647,7 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
let inputstr = sys.read().trim();
// screw with the comma-separating because shrug
bStatus.vars[endArg.troValue] = inputstr;
bStatus.vars[endArg.troValue] = new BasicVar(inputstr, JStoBASICtype(inputstr));
// return raw input string
return inputstr;

View File

@@ -0,0 +1,3 @@
// load a BASIC rom
sys.mapRom(1);
execApp(sys.romReadAll());

View File

@@ -4,10 +4,7 @@ import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import net.torvald.tsvm.peripheral.BasicBios;
import net.torvald.tsvm.peripheral.BasicRom;
import net.torvald.tsvm.peripheral.GenericBios;
import net.torvald.tsvm.peripheral.VMProgramRom;
import net.torvald.tsvm.peripheral.*;
public class AppLoader {
@@ -31,7 +28,8 @@ public class AppLoader {
// val vm = VM(64.kB(), TheRealWorld(), arrayOf(GenericBios))
//VM vm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{GenericBios.INSTANCE});
VM vm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{BasicBios.INSTANCE, BasicRom.INSTANCE});
//VM vm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{BasicBios.INSTANCE, BasicRom.INSTANCE});
VM vm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{OEMBios.INSTANCE, BasicRom.INSTANCE});
new LwjglApplication(new VMGUI(vm, appConfig), appConfig);
}

View File

@@ -17,7 +17,7 @@ class VMJSR223Delegate(val vm: VM) {
vm.romMapping = slot.and(255)
}
fun romReadAll(): String {
if (vm.romMapping == 255) return ""
if (vm.romMapping == 255 || vm.romMapping !in vm.roms.indices || vm.roms[vm.romMapping] == null) return ""
return vm.roms[vm.romMapping]!!.readAll()
}

View File

@@ -0,0 +1,28 @@
package net.torvald.tsvm.peripheral
import net.torvald.tsvm.CompressorDelegate
import net.torvald.tsvm.CompressorDelegate.GZIP_HEADER
import net.torvald.tsvm.VM
import net.torvald.tsvm.startsWith
import java.io.File
object OEMBios : VMProgramRom {
private val contents: ByteArray
init {
val bytes = File("./assets/bios/TBMBIOS.js").readBytes()
contents = bytes.sliceArray(0 until minOf(65536, bytes.size))
}
override fun readAll(): String {
// check if bios is compressed in gzip
return if (contents.startsWith(GZIP_HEADER))
CompressorDelegate.decomp(contents).toString(VM.CHARSET)
else
contents.toString(VM.CHARSET)
}
override fun get(addr: Int): Byte = contents[addr]
}