Simulate Thunderclock in Slot 4
See the new sample for details/example. Note that reading 12/24-hour time formats that have colons will not currently work, as the colons will terminate input and result in invisible ?EXTRA IGNORED errors. Fixes #44
This commit is contained in:
parent
f18ad47d1c
commit
555f8de2ae
|
@ -44,7 +44,7 @@ CodeMirror.defineMode('basic', function(config, parserConfig) {
|
||||||
"HPLOT": STATEMENT,
|
"HPLOT": STATEMENT,
|
||||||
"HTAB": STATEMENT,
|
"HTAB": STATEMENT,
|
||||||
"IF": STATEMENT,
|
"IF": STATEMENT,
|
||||||
"IN#": UNSUPPORTED,
|
"IN#": STATEMENT,
|
||||||
"INPUT": STATEMENT,
|
"INPUT": STATEMENT,
|
||||||
"INT": FUNCTION,
|
"INT": FUNCTION,
|
||||||
"INVERSE": STATEMENT,
|
"INVERSE": STATEMENT,
|
||||||
|
|
134
dos.js
134
dos.js
|
@ -39,6 +39,11 @@ function DOS(tty) {
|
||||||
tty_readChar,
|
tty_readChar,
|
||||||
tty_writeChar,
|
tty_writeChar,
|
||||||
|
|
||||||
|
// Hooked I/O routines
|
||||||
|
hooked_readLine,
|
||||||
|
hooked_readChar,
|
||||||
|
hooked_writeChar,
|
||||||
|
|
||||||
// character output state
|
// character output state
|
||||||
commandBuffer = "",
|
commandBuffer = "",
|
||||||
commandMode = false,
|
commandMode = false,
|
||||||
|
@ -358,8 +363,25 @@ function DOS(tty) {
|
||||||
args = parseArgs(m[2]);
|
args = parseArgs(m[2]);
|
||||||
if (slot === 0) {
|
if (slot === 0) {
|
||||||
if (tty.setFirmwareActive) { tty.setFirmwareActive(false); }
|
if (tty.setFirmwareActive) { tty.setFirmwareActive(false); }
|
||||||
|
hooked_writeChar = tty_writeChar;
|
||||||
} else if (slot === 3) {
|
} else if (slot === 3) {
|
||||||
if (tty.setFirmwareActive) { tty.setFirmwareActive(true); }
|
if (tty.setFirmwareActive) { tty.setFirmwareActive(true); }
|
||||||
|
hooked_writeChar = tty_writeChar;
|
||||||
|
} else if (slot === 4) {
|
||||||
|
hooked_writeChar = clock_writeChar;
|
||||||
|
} else {
|
||||||
|
doserror(DOSErrors.RANGE_ERROR);
|
||||||
|
}
|
||||||
|
} else if ((m = command.match(/^IN#\s*([\x20-\x2B\x2D-\x7E]+)(,[\x20-\x7E]*)?/))) {
|
||||||
|
// IN# slot Direct input to slot
|
||||||
|
slot = Number(m[1]);
|
||||||
|
args = parseArgs(m[2]);
|
||||||
|
if (slot === 0 || slot === 3) {
|
||||||
|
hooked_readLine = tty_readLine;
|
||||||
|
hooked_readChar = tty_readChar;
|
||||||
|
} else if (slot === 4) {
|
||||||
|
hooked_readLine = clock_readLine;
|
||||||
|
hooked_readChar = clock_readChar;
|
||||||
} else {
|
} else {
|
||||||
doserror(DOSErrors.RANGE_ERROR);
|
doserror(DOSErrors.RANGE_ERROR);
|
||||||
}
|
}
|
||||||
|
@ -381,7 +403,15 @@ function DOS(tty) {
|
||||||
tty_readChar = tty.readChar;
|
tty_readChar = tty.readChar;
|
||||||
tty_writeChar = tty.writeChar;
|
tty_writeChar = tty.writeChar;
|
||||||
|
|
||||||
tty.readLine = function dos_readLine(callback, prompt) {
|
hooked_readLine = tty_readLine;
|
||||||
|
hooked_readChar = tty_readChar;
|
||||||
|
hooked_writeChar = tty_writeChar;
|
||||||
|
|
||||||
|
tty.readLine = dos_readLine;
|
||||||
|
tty.readChar = dos_readChar;
|
||||||
|
tty.writeChar = dos_writeChar;
|
||||||
|
|
||||||
|
function dos_readLine(callback, prompt) {
|
||||||
|
|
||||||
var string = "", c, data, len, fp, buffer;
|
var string = "", c, data, len, fp, buffer;
|
||||||
if (mode === "r") {
|
if (mode === "r") {
|
||||||
|
@ -415,12 +445,11 @@ function DOS(tty) {
|
||||||
// Non-blocking return
|
// Non-blocking return
|
||||||
setTimeout(function() { callback(string); }, 0);
|
setTimeout(function() { callback(string); }, 0);
|
||||||
} else {
|
} else {
|
||||||
tty_readLine(callback, prompt);
|
hooked_readLine(callback, prompt);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
};
|
function dos_readChar(callback) {
|
||||||
|
|
||||||
tty.readChar = function dos_readChar(callback) {
|
|
||||||
|
|
||||||
var character = "";
|
var character = "";
|
||||||
if (mode === "r") {
|
if (mode === "r") {
|
||||||
|
@ -432,17 +461,17 @@ function DOS(tty) {
|
||||||
activebuffer.filepointer += 1;
|
activebuffer.filepointer += 1;
|
||||||
|
|
||||||
if (monico & MON_I && tty) {
|
if (monico & MON_I && tty) {
|
||||||
tty_writeChar(character);
|
hooked_writeChar(character);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Non-blocking return
|
// Non-blocking return
|
||||||
setTimeout(function() { callback(character); }, 0);
|
setTimeout(function() { callback(character); }, 0);
|
||||||
} else {
|
} else {
|
||||||
tty_readChar(callback);
|
hooked_readChar(callback);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
tty.writeChar = function dos_writeChar(c) {
|
function dos_writeChar(c) {
|
||||||
|
|
||||||
if (commandMode) {
|
if (commandMode) {
|
||||||
if (c === "\r") {
|
if (c === "\r") {
|
||||||
|
@ -463,7 +492,7 @@ function DOS(tty) {
|
||||||
var buf, d;
|
var buf, d;
|
||||||
|
|
||||||
if (monico & MON_O) {
|
if (monico & MON_O) {
|
||||||
tty_writeChar(c);
|
hooked_writeChar(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = activebuffer;
|
buf = activebuffer;
|
||||||
|
@ -484,8 +513,89 @@ function DOS(tty) {
|
||||||
|
|
||||||
buf.filepointer += 1;
|
buf.filepointer += 1;
|
||||||
} else {
|
} else {
|
||||||
tty_writeChar(c);
|
hooked_writeChar(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Clock routine - vaguely ThunderClock compatible
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
var clockbuf = '';
|
||||||
|
function clock_writeChar(c) {
|
||||||
|
var DAYS = ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'];
|
||||||
|
var MONTHS = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN',
|
||||||
|
'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'];
|
||||||
|
function spad2(s) {
|
||||||
|
return ('00' + String(s)).slice(-2);
|
||||||
|
}
|
||||||
|
function zpad2(s) {
|
||||||
|
return ('00' + String(s)).slice(-2);
|
||||||
|
}
|
||||||
|
function zpad3(s) {
|
||||||
|
return ('000' + String(s)).slice(-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // writeChar
|
var now = new Date();
|
||||||
|
switch (c) {
|
||||||
|
default:
|
||||||
|
case '%': // AM/PM ASCII string mode - e.g. "TUE MAY 12 4:32:55 PM"
|
||||||
|
case '>': // AM/PM ASCII string mode - e.g. "TUE MAY 12 4:32:55 PM"
|
||||||
|
clockbuf =
|
||||||
|
DAYS[now.getDay()] + ' ' +
|
||||||
|
MONTHS[now.getMonth()] + ' ' +
|
||||||
|
now.getDate() + ' ' +
|
||||||
|
spad2((now.getHours() === 0 ? 12 : now.getHours() > 12 ? now.getHours() - 12 : now.getHours())) + ':' +
|
||||||
|
zpad2(now.getMinutes()) + ':' +
|
||||||
|
zpad2(now.getSeconds()) + ' ' +
|
||||||
|
(now.getHours() < 12 ? 'AM' : 'PM');
|
||||||
|
break;
|
||||||
|
case '&': // 24 hour ASCII string - e.g. "TUE MAY 12 16:32:55"
|
||||||
|
case '<': // 24 hour ASCII string - e.g. "TUE MAY 12 16:32:55"
|
||||||
|
clockbuf =
|
||||||
|
DAYS[now.getDay()] + ' ' +
|
||||||
|
MONTHS[now.getMonth()] + ' ' +
|
||||||
|
now.getDate() + ' ' +
|
||||||
|
spad2(now.getHours()) + ':' +
|
||||||
|
zpad2(now.getMinutes()) + ':' +
|
||||||
|
zpad2(now.getSeconds()) + ' ' +
|
||||||
|
(now.getHours() < 12 ? 'AM' : 'PM');
|
||||||
|
break;
|
||||||
|
case ' ': // Mountain Computer Apple Clock Format - e.g. "05/12 16;32;55.000"
|
||||||
|
clockbuf =
|
||||||
|
zpad2(now.getMonth()+1) + '/' +
|
||||||
|
zpad2(now.getDate()) + ' ' +
|
||||||
|
zpad2(now.getHours()) + ';' +
|
||||||
|
zpad2(now.getMinutes()) + ';' +
|
||||||
|
zpad2(now.getSeconds()) + '.' +
|
||||||
|
zpad3(now.getMilliseconds());
|
||||||
|
break;
|
||||||
|
case '#': // Numeric format, e.g. MO,DW,DT,HR,MN,SEC
|
||||||
|
clockbuf = [
|
||||||
|
now.getMonth()+1,
|
||||||
|
now.getDay(),
|
||||||
|
now.getDate(),
|
||||||
|
now.getHours(),
|
||||||
|
now.getMinutes(),
|
||||||
|
now.getSeconds()
|
||||||
|
].join(',');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
clockbuf += '\r';
|
||||||
|
}
|
||||||
|
function clock_readLine(callback, prompt) {
|
||||||
|
tty.writeString(prompt); // TODO: Correct? Newline?
|
||||||
|
var tmp = clockbuf;
|
||||||
|
clockbuf = '';
|
||||||
|
callback(tmp);
|
||||||
|
}
|
||||||
|
function clock_readChar(callback) {
|
||||||
|
if (!clockbuf.length) {
|
||||||
|
callback('\r');
|
||||||
|
} else {
|
||||||
|
var c = clockbuf.substring(0, 1);
|
||||||
|
clockbuf = clockbuf.slice(1);
|
||||||
|
callback(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,7 +169,6 @@ can be literals (unquoted strings), strings, or numbers
|
||||||
<h3>Native Platform Interaction <var>- NOT IMPLEMENTED</var></h3>
|
<h3>Native Platform Interaction <var>- NOT IMPLEMENTED</var></h3>
|
||||||
<dl>
|
<dl>
|
||||||
<dt>HIMEM: <var>aexpr</var><dd>Set upper address of variable memory
|
<dt>HIMEM: <var>aexpr</var><dd>Set upper address of variable memory
|
||||||
<dt>IN# <var>aexpr</var><dd>Direct input from slot
|
|
||||||
<dt>LOMEM: <var>aexpr</var><dd>Set lower address of variable memory
|
<dt>LOMEM: <var>aexpr</var><dd>Set lower address of variable memory
|
||||||
<dt>WAIT <var>aexpr</var>, <var>aexpr</var> [, <var>aexpr</var>]<dd>Wait until memory location masked by second argument equals third argument (or zero)
|
<dt>WAIT <var>aexpr</var>, <var>aexpr</var> [, <var>aexpr</var>]<dd>Wait until memory location masked by second argument equals third argument (or zero)
|
||||||
</dl>
|
</dl>
|
||||||
|
@ -234,6 +233,13 @@ can be literals (unquoted strings), strings, or numbers
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>PR#0</code> — set 40 column mode
|
<li><code>PR#0</code> — set 40 column mode
|
||||||
<li><code>PR#3</code> — set 80 column mode
|
<li><code>PR#3</code> — set 80 column mode
|
||||||
|
<li><code>PR#4</code> — write to Thunderclock
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<dt>IN# <var>aexpr</var><dd>Direct output to slot
|
||||||
|
<ul>
|
||||||
|
<li><code>IN#0</code> — read input from keyboard or DOS
|
||||||
|
<li><code>IN#4</code> — read from Thunderclock
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</dl>
|
</dl>
|
||||||
|
|
|
@ -93,6 +93,7 @@ sample.onelinetrain One Liner Train (Chris ten Den)
|
||||||
sample.piglatin Pig Latin Translator (Gregg Buntin)
|
sample.piglatin Pig Latin Translator (Gregg Buntin)
|
||||||
sample.nuclear Nuclear Power Plant (Stephen R. Berggren c/o Kevin Riggle)
|
sample.nuclear Nuclear Power Plant (Stephen R. Berggren c/o Kevin Riggle)
|
||||||
sample.factors Prime Factors (Cristiano Trabuio)
|
sample.factors Prime Factors (Cristiano Trabuio)
|
||||||
|
sample.thunderclock Thunderclock (incomplete)
|
||||||
|
|
||||||
# ____________________________________________
|
# ____________________________________________
|
||||||
# Traveller RPG Utilities
|
# Traveller RPG Utilities
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
10 PRINT "Mountain Clock Format"
|
||||||
|
20 PRINT CHR$(4);"PR#4"
|
||||||
|
30 PRINT CHR$(4);"IN#4"
|
||||||
|
40 INPUT " ";T$
|
||||||
|
50 PRINT CHR$(4);"PR#0"
|
||||||
|
60 PRINT CHR$(4);"IN#0"
|
||||||
|
70 PRINT T$
|
||||||
|
80 PRINT
|
||||||
|
|
||||||
|
100 PRINT "Numeric Format"
|
||||||
|
110 PRINT CHR$(4);"PR#4"
|
||||||
|
120 PRINT CHR$(4);"IN#4"
|
||||||
|
130 INPUT "#";MO,DW,DT,HR,MN,SEC
|
||||||
|
140 PRINT CHR$(4);"PR#0"
|
||||||
|
150 PRINT CHR$(4);"IN#0"
|
||||||
|
160 PRINT "Month: ";MO
|
||||||
|
161 PRINT "Day: ";DW
|
||||||
|
162 PRINT "Date: ";DT
|
||||||
|
163 PRINT "Hours: ";HR
|
||||||
|
164 PRINT "Minutes: ";MN
|
||||||
|
165 PRINT "Seconds: ";SEC
|
3
tty.js
3
tty.js
|
@ -236,7 +236,8 @@ function TTY(screenElement, keyboardElement) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.setFirmwareActive = function setFirmwareActive(active) {
|
this.setFirmwareActive = function setFirmwareActive(active) {
|
||||||
init(active, 24, active ? 80 : 40);
|
if (active !== firmwareActive)
|
||||||
|
init(active, 24, active ? 80 : 40);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.isFirmwareActive = function isFirmwareActive() {
|
this.isFirmwareActive = function isFirmwareActive() {
|
||||||
|
|
Loading…
Reference in New Issue