Implement prelude-loading mechanism
This commit is contained in:
@@ -46,3 +46,12 @@ registers: `xBUF`, `xHEAD` and `xTAIL`:
|
||||
In order to be distinguishable from the empty state, the ring buffers
|
||||
must never be completely full -- there must always be *at least one*
|
||||
unoccupied byte between the tail and the head.
|
||||
|
||||
# System status
|
||||
|
||||
| Name | Offset | Size / B | Access |
|
||||
|----------|--------|----------|--------------|
|
||||
| SYSREADY | 68 | 1 | atomic write |
|
||||
|
||||
The `SYSREADY` register is used to indicate when the system has booted
|
||||
up and is ready for user input.
|
||||
|
||||
29
emu.js
29
emu.js
@@ -4,10 +4,11 @@ const TXHEAD = 64;
|
||||
const TXTAIL = 65;
|
||||
const RXHEAD = 66;
|
||||
const RXTAIL = 67;
|
||||
const SYSREADY = 68;
|
||||
|
||||
const TXBUF_SIZE = 32;
|
||||
const RXBUF_SIZE = 32;
|
||||
const PERIPHS_SIZE = 68;
|
||||
const PERIPHS_SIZE = 69; // Nice
|
||||
|
||||
const POLL_INTERVAL_MS = 20;
|
||||
|
||||
@@ -44,13 +45,18 @@ class Emulator {
|
||||
end: { x: 0, y: 0 }
|
||||
};
|
||||
this.idle_timer = null;
|
||||
this.input_enable = false;
|
||||
document.addEventListener('keydown', (e) => this.handle_keydown(e));
|
||||
|
||||
this.flush_output();
|
||||
document.getElementById('cursor').classList.add('blinking');
|
||||
|
||||
this.worker = new Worker('boot.js');
|
||||
this.worker.postMessage(this.mem);
|
||||
|
||||
fetch('prelude.f')
|
||||
.then(res => res.text())
|
||||
.then(text => {
|
||||
for (const cu of this.encoder.encode(text))
|
||||
this.rx_queue.push(cu);
|
||||
});
|
||||
}
|
||||
|
||||
poll() {
|
||||
@@ -65,6 +71,15 @@ class Emulator {
|
||||
if (this.fifo_next(rxtail) != rxhead)
|
||||
this.handle_rx_data(rxhead, rxtail);
|
||||
}
|
||||
|
||||
if (!this.input_enable) {
|
||||
const sysready = Atomics.load(this.mem_u8, SYSREADY);
|
||||
if (sysready != 0) {
|
||||
this.input_enable = true;
|
||||
this.flush_output();
|
||||
document.getElementById('cursor').classList.add('blinking');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fifo_next(idx) {
|
||||
@@ -118,6 +133,9 @@ class Emulator {
|
||||
}
|
||||
|
||||
handle_keydown(e) {
|
||||
if (!this.input_enable)
|
||||
return;
|
||||
|
||||
if (e.key.length == 1 && !e.ctrlKey && !e.altKey && !e.metaKey) {
|
||||
this.shift_up(this.cursor);
|
||||
this.grid[this.cursor.y][this.cursor.x] = e.key;
|
||||
@@ -239,7 +257,8 @@ class Emulator {
|
||||
const html = this.grid.map((row, y) => {
|
||||
return row.map((c, x) => {
|
||||
const ec = this.html_escape(c);
|
||||
if (x == this.cursor.x && y == this.cursor.y)
|
||||
if (this.input_enable
|
||||
&& x == this.cursor.x && y == this.cursor.y)
|
||||
return '<span id="cursor">' + ec + '</span>';
|
||||
else
|
||||
return ec;
|
||||
|
||||
Reference in New Issue
Block a user