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
|
In order to be distinguishable from the empty state, the ring buffers
|
||||||
must never be completely full -- there must always be *at least one*
|
must never be completely full -- there must always be *at least one*
|
||||||
unoccupied byte between the tail and the head.
|
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 TXTAIL = 65;
|
||||||
const RXHEAD = 66;
|
const RXHEAD = 66;
|
||||||
const RXTAIL = 67;
|
const RXTAIL = 67;
|
||||||
|
const SYSREADY = 68;
|
||||||
|
|
||||||
const TXBUF_SIZE = 32;
|
const TXBUF_SIZE = 32;
|
||||||
const RXBUF_SIZE = 32;
|
const RXBUF_SIZE = 32;
|
||||||
const PERIPHS_SIZE = 68;
|
const PERIPHS_SIZE = 69; // Nice
|
||||||
|
|
||||||
const POLL_INTERVAL_MS = 20;
|
const POLL_INTERVAL_MS = 20;
|
||||||
|
|
||||||
@@ -44,13 +45,18 @@ class Emulator {
|
|||||||
end: { x: 0, y: 0 }
|
end: { x: 0, y: 0 }
|
||||||
};
|
};
|
||||||
this.idle_timer = null;
|
this.idle_timer = null;
|
||||||
|
this.input_enable = false;
|
||||||
document.addEventListener('keydown', (e) => this.handle_keydown(e));
|
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 = new Worker('boot.js');
|
||||||
this.worker.postMessage(this.mem);
|
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() {
|
poll() {
|
||||||
@@ -65,6 +71,15 @@ class Emulator {
|
|||||||
if (this.fifo_next(rxtail) != rxhead)
|
if (this.fifo_next(rxtail) != rxhead)
|
||||||
this.handle_rx_data(rxhead, rxtail);
|
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) {
|
fifo_next(idx) {
|
||||||
@@ -118,6 +133,9 @@ class Emulator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handle_keydown(e) {
|
handle_keydown(e) {
|
||||||
|
if (!this.input_enable)
|
||||||
|
return;
|
||||||
|
|
||||||
if (e.key.length == 1 && !e.ctrlKey && !e.altKey && !e.metaKey) {
|
if (e.key.length == 1 && !e.ctrlKey && !e.altKey && !e.metaKey) {
|
||||||
this.shift_up(this.cursor);
|
this.shift_up(this.cursor);
|
||||||
this.grid[this.cursor.y][this.cursor.x] = e.key;
|
this.grid[this.cursor.y][this.cursor.x] = e.key;
|
||||||
@@ -239,7 +257,8 @@ class Emulator {
|
|||||||
const html = this.grid.map((row, y) => {
|
const html = this.grid.map((row, y) => {
|
||||||
return row.map((c, x) => {
|
return row.map((c, x) => {
|
||||||
const ec = this.html_escape(c);
|
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>';
|
return '<span id="cursor">' + ec + '</span>';
|
||||||
else
|
else
|
||||||
return ec;
|
return ec;
|
||||||
|
|||||||
Reference in New Issue
Block a user