Reduce load time #2

Merged
cdo merged 8 commits from reduce-load-time into main 2026-03-20 13:13:22 +00:00
4 changed files with 52 additions and 46 deletions
Showing only changes of commit 2c13ad4e1f - Show all commits

View File

@@ -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
View File

@@ -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;

View File

@@ -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

View File

@@ -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