Handle prelude loading message in JS rather than Forth
This commit is contained in:
@@ -99,6 +99,9 @@ unoccupied byte between the tail and the head.
|
|||||||
| Name | Address | Size / B | Access |
|
| Name | Address | Size / B | Access |
|
||||||
|----------|---------|----------|--------------|
|
|----------|---------|----------|--------------|
|
||||||
| SYSREADY | 110h | 4 | atomic write |
|
| SYSREADY | 110h | 4 | atomic write |
|
||||||
|
| SYSINTER | 114h | 4 | atomic read |
|
||||||
|
|
||||||
The `SYSREADY` register is used to indicate when the system has booted
|
The `SYSREADY` register is used to indicate when the system has booted
|
||||||
up and is ready for user input.
|
up and is ready for user input. `SYSINTER` is set (and notified on)
|
||||||
|
once the emulator has enabled user input and the system is
|
||||||
|
interactive.
|
||||||
|
|||||||
35
emu.js
35
emu.js
@@ -6,6 +6,7 @@ const RXHEAD = 0x108;
|
|||||||
const RXTAIL = 0x10c;
|
const RXTAIL = 0x10c;
|
||||||
|
|
||||||
const SYSREADY = 0x110;
|
const SYSREADY = 0x110;
|
||||||
|
const SYSINTER = 0x114;
|
||||||
|
|
||||||
const DOT_INTERVAL_MS = 120;
|
const DOT_INTERVAL_MS = 120;
|
||||||
const PERIPHS_SIZE = 0x200;
|
const PERIPHS_SIZE = 0x200;
|
||||||
@@ -50,14 +51,18 @@ class Emulator {
|
|||||||
document.addEventListener('keydown', (e) => this.handle_keydown(e));
|
document.addEventListener('keydown', (e) => this.handle_keydown(e));
|
||||||
window.addEventListener('resize', () => this.handle_resize());
|
window.addEventListener('resize', () => this.handle_resize());
|
||||||
|
|
||||||
|
this.forth = new Worker('boot.js', { type: 'module' });
|
||||||
|
|
||||||
this.print("Assembling kernel ");
|
this.print("Assembling kernel ");
|
||||||
const dots = setInterval(() => this.print("."), DOT_INTERVAL_MS);
|
this.dots = setInterval(() => this.print("."), DOT_INTERVAL_MS);
|
||||||
this.worker = new Worker('boot.js', { type: 'module' });
|
this.forth.postMessage({ type: "load", mem: this.mem });
|
||||||
this.worker.postMessage({ type: "load", mem: this.mem });
|
this.forth.onmessage = (e) => {
|
||||||
this.worker.onmessage = (e) => {
|
clearInterval(this.dots);
|
||||||
clearInterval(dots);
|
|
||||||
this.print(" done\n");
|
this.print(" done\n");
|
||||||
this.worker.postMessage({ type: "boot" });
|
|
||||||
|
this.print("Loading prelude ");
|
||||||
|
this.forth.postMessage({ type: "boot" });
|
||||||
|
this.dots = setInterval(() => this.print("."), DOT_INTERVAL_MS);
|
||||||
};
|
};
|
||||||
|
|
||||||
fetch('prelude.f')
|
fetch('prelude.f')
|
||||||
@@ -84,9 +89,15 @@ class Emulator {
|
|||||||
if (!this.input_enable) {
|
if (!this.input_enable) {
|
||||||
const sysready = Atomics.load(this.mem_u8, SYSREADY);
|
const sysready = Atomics.load(this.mem_u8, SYSREADY);
|
||||||
if (sysready != 0) {
|
if (sysready != 0) {
|
||||||
|
clearInterval(this.dots);
|
||||||
|
this.print(" done\n");
|
||||||
|
|
||||||
|
Atomics.store(this.mem_u8, SYSINTER, 1);
|
||||||
|
Atomics.notify(this.mem_i32, SYSINTER / 4);
|
||||||
|
|
||||||
this.input_enable = true;
|
this.input_enable = true;
|
||||||
|
this.blink = true;
|
||||||
this.flush_output();
|
this.flush_output();
|
||||||
document.getElementById('cursor').classList.add('blinking');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,12 +191,14 @@ class Emulator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
this.blink = false;
|
||||||
this.flush_output();
|
this.flush_output();
|
||||||
|
|
||||||
document.getElementById('cursor').classList.remove('blinking');
|
document.getElementById('cursor').classList.remove('blinking');
|
||||||
if (this.idle_timer)
|
if (this.idle_timer)
|
||||||
clearTimeout(this.idle_timer);
|
clearTimeout(this.idle_timer);
|
||||||
this.idle_timer = setTimeout(() => {
|
this.idle_timer = setTimeout(() => {
|
||||||
|
this.blink = true;
|
||||||
document.getElementById('cursor').classList.add('blinking');
|
document.getElementById('cursor').classList.add('blinking');
|
||||||
}, CURSOR_IDLE_TIME_MS);
|
}, CURSOR_IDLE_TIME_MS);
|
||||||
}
|
}
|
||||||
@@ -272,10 +285,12 @@ class Emulator {
|
|||||||
return row.map((c, x) => {
|
return row.map((c, x) => {
|
||||||
const ec = this.html_escape(c);
|
const ec = this.html_escape(c);
|
||||||
if (this.input_enable
|
if (this.input_enable
|
||||||
&& x == this.cursor.x && y == this.cursor.y)
|
&& x == this.cursor.x && y == this.cursor.y) {
|
||||||
return '<span id="cursor">' + ec + '</span>';
|
const cl = this.blink ? 'class="blinking"' : '';
|
||||||
else
|
return `<span id="cursor" ${cl}>` + ec + '</span>';
|
||||||
|
} else {
|
||||||
return ec;
|
return ec;
|
||||||
|
}
|
||||||
}).join('').trimEnd();
|
}).join('').trimEnd();
|
||||||
}).join('\n');
|
}).join('\n');
|
||||||
this.output.innerHTML = html;
|
this.output.innerHTML = html;
|
||||||
|
|||||||
40
prelude.f
40
prelude.f
@@ -1,12 +1,5 @@
|
|||||||
76 EMIT 111 EMIT 97 EMIT 100 EMIT 105 EMIT 110 EMIT 103 EMIT 32 EMIT
|
|
||||||
112 EMIT 114 EMIT 101 EMIT 108 EMIT 117 EMIT 100 EMIT 101 EMIT 32 EMIT
|
|
||||||
|
|
||||||
: \ KEY 10 = 0BRANCH [ -20 , ] ; IMMEDIATE \ Now we have line comments :)
|
: \ KEY 10 = 0BRANCH [ -20 , ] ; IMMEDIATE \ Now we have line comments :)
|
||||||
|
|
||||||
\ We'll periodically sprinkle these in so that it's clear to the user
|
|
||||||
\ that things are happening.
|
|
||||||
46 EMIT
|
|
||||||
|
|
||||||
\ Conditionals
|
\ Conditionals
|
||||||
|
|
||||||
: IF
|
: IF
|
||||||
@@ -27,8 +20,6 @@
|
|||||||
SWAP !
|
SWAP !
|
||||||
; IMMEDIATE
|
; IMMEDIATE
|
||||||
|
|
||||||
46 EMIT
|
|
||||||
|
|
||||||
\ Loops
|
\ Loops
|
||||||
|
|
||||||
: BEGIN HERE @ ; IMMEDIATE
|
: BEGIN HERE @ ; IMMEDIATE
|
||||||
@@ -43,8 +34,6 @@
|
|||||||
HERE @ - ,
|
HERE @ - ,
|
||||||
; IMMEDIATE
|
; IMMEDIATE
|
||||||
|
|
||||||
46 EMIT
|
|
||||||
|
|
||||||
\ Recursive calls
|
\ Recursive calls
|
||||||
|
|
||||||
: RECURSE LATEST @ >CFA , ; IMMEDIATE
|
: RECURSE LATEST @ >CFA , ; IMMEDIATE
|
||||||
@@ -61,8 +50,6 @@
|
|||||||
|
|
||||||
( ( Take that, C ) )
|
( ( Take that, C ) )
|
||||||
|
|
||||||
46 EMIT
|
|
||||||
|
|
||||||
\ Printing utilities
|
\ Printing utilities
|
||||||
|
|
||||||
: CR 10 EMIT ;
|
: CR 10 EMIT ;
|
||||||
@@ -80,8 +67,6 @@
|
|||||||
+ EMIT
|
+ EMIT
|
||||||
;
|
;
|
||||||
|
|
||||||
CHAR . EMIT
|
|
||||||
|
|
||||||
: .
|
: .
|
||||||
\ Handle negatives
|
\ Handle negatives
|
||||||
DUP 0< IF CHAR - EMIT NEGATE THEN
|
DUP 0< IF CHAR - EMIT NEGATE THEN
|
||||||
@@ -110,8 +95,6 @@ CHAR . EMIT
|
|||||||
2DROP
|
2DROP
|
||||||
;
|
;
|
||||||
|
|
||||||
CHAR . EMIT
|
|
||||||
|
|
||||||
: TYPE ( addr len -- )
|
: TYPE ( addr len -- )
|
||||||
BEGIN
|
BEGIN
|
||||||
DUP 0= IF 2DROP EXIT THEN
|
DUP 0= IF 2DROP EXIT THEN
|
||||||
@@ -120,8 +103,6 @@ CHAR . EMIT
|
|||||||
AGAIN
|
AGAIN
|
||||||
;
|
;
|
||||||
|
|
||||||
CHAR . EMIT
|
|
||||||
|
|
||||||
: C, HERE @ C! 1 HERE +! ;
|
: C, HERE @ C! 1 HERE +! ;
|
||||||
|
|
||||||
: ."
|
: ."
|
||||||
@@ -151,8 +132,6 @@ CHAR . EMIT
|
|||||||
THEN
|
THEN
|
||||||
; IMMEDIATE
|
; IMMEDIATE
|
||||||
|
|
||||||
CHAR . EMIT
|
|
||||||
|
|
||||||
\ Misc utilities
|
\ Misc utilities
|
||||||
|
|
||||||
: NIP SWAP DROP ;
|
: NIP SWAP DROP ;
|
||||||
@@ -171,8 +150,6 @@ CHAR . EMIT
|
|||||||
|
|
||||||
: [COMPILE] ' , ; IMMEDIATE
|
: [COMPILE] ' , ; IMMEDIATE
|
||||||
|
|
||||||
CHAR . EMIT
|
|
||||||
|
|
||||||
\ Constants, variables and values
|
\ Constants, variables and values
|
||||||
|
|
||||||
: CONSTANT
|
: CONSTANT
|
||||||
@@ -204,8 +181,6 @@ CHAR . EMIT
|
|||||||
THEN
|
THEN
|
||||||
; IMMEDIATE
|
; IMMEDIATE
|
||||||
|
|
||||||
CHAR . EMIT
|
|
||||||
|
|
||||||
\ Peripheral register addresses
|
\ Peripheral register addresses
|
||||||
|
|
||||||
HEX
|
HEX
|
||||||
@@ -217,11 +192,10 @@ HEX
|
|||||||
108 CONSTANT RXHEAD
|
108 CONSTANT RXHEAD
|
||||||
10C CONSTANT RXTAIL
|
10C CONSTANT RXTAIL
|
||||||
110 CONSTANT SYSREADY
|
110 CONSTANT SYSREADY
|
||||||
|
114 CONSTANT SYSINTER
|
||||||
|
|
||||||
DECIMAL
|
DECIMAL
|
||||||
|
|
||||||
46 EMIT
|
|
||||||
|
|
||||||
\ A better word-not-found handler
|
\ A better word-not-found handler
|
||||||
|
|
||||||
: ANY-RX? RXHEAD AC@ RXTAIL AC@ <> ;
|
: ANY-RX? RXHEAD AC@ RXTAIL AC@ <> ;
|
||||||
@@ -244,8 +218,6 @@ DECIMAL
|
|||||||
|
|
||||||
' WNF-HANDLER TO WNFHOOK
|
' WNF-HANDLER TO WNFHOOK
|
||||||
|
|
||||||
CHAR . EMIT
|
|
||||||
|
|
||||||
\ Version number
|
\ Version number
|
||||||
|
|
||||||
0 CONSTANT VERSION-MAJOR
|
0 CONSTANT VERSION-MAJOR
|
||||||
@@ -258,8 +230,6 @@ CHAR . EMIT
|
|||||||
CHAR . EMIT VERSION-PATCH .
|
CHAR . EMIT VERSION-PATCH .
|
||||||
;
|
;
|
||||||
|
|
||||||
CHAR . EMIT
|
|
||||||
|
|
||||||
\ Welcome banner
|
\ Welcome banner
|
||||||
|
|
||||||
: BANNER
|
: BANNER
|
||||||
@@ -277,8 +247,8 @@ CHAR . EMIT
|
|||||||
CR
|
CR
|
||||||
;
|
;
|
||||||
|
|
||||||
." done" CR
|
\ Set SYSREADY high and wait until interactive
|
||||||
BANNER
|
|
||||||
|
|
||||||
\ Set SYSREADY high to enable user input
|
|
||||||
1 SYSREADY AC!
|
1 SYSREADY AC!
|
||||||
|
SYSINTER WAIT DROP
|
||||||
|
|
||||||
|
BANNER
|
||||||
|
|||||||
18
wipforth.ws
18
wipforth.ws
@@ -635,6 +635,15 @@
|
|||||||
end
|
end
|
||||||
call next
|
call next
|
||||||
|
|
||||||
|
.func wait
|
||||||
|
.elem codewords wait WAIT_CODEWORD
|
||||||
|
call pop
|
||||||
|
i32.const 0
|
||||||
|
i64.const -1
|
||||||
|
memory.atomic.wait32 2 0
|
||||||
|
call push
|
||||||
|
call next
|
||||||
|
|
||||||
;; Core utility words
|
;; Core utility words
|
||||||
|
|
||||||
.func exit
|
.func exit
|
||||||
@@ -1226,6 +1235,15 @@ COPY:
|
|||||||
.word COPY_CODEWORD
|
.word COPY_CODEWORD
|
||||||
.def PREV _COPY
|
.def PREV _COPY
|
||||||
|
|
||||||
|
_WAIT:
|
||||||
|
.word PREV
|
||||||
|
.byte 4
|
||||||
|
.utf8 "WAIT"
|
||||||
|
.align
|
||||||
|
WAIT:
|
||||||
|
.word WAIT_CODEWORD
|
||||||
|
.def PREV _WAIT
|
||||||
|
|
||||||
_EXIT:
|
_EXIT:
|
||||||
.word PREV
|
.word PREV
|
||||||
.byte 4
|
.byte 4
|
||||||
|
|||||||
Reference in New Issue
Block a user