Rejig serial periph
This commit is contained in:
27
README.md
27
README.md
@@ -30,20 +30,19 @@ these headers.
|
||||
|--------|--------|----------|--------------|
|
||||
| TXBUF | 0 | 32 | write |
|
||||
| RXBUF | 32 | 32 | read |
|
||||
| TXDATA | 64 | 1 | atomic write |
|
||||
| TXHEAD | 65 | 1 | atomic read |
|
||||
| TXTAIL | 66 | 1 | atomic write |
|
||||
| RXDATA | 67 | 1 | atomic read |
|
||||
| RXHEAD | 68 | 1 | atomic write |
|
||||
| RXTAIL | 69 | 1 | atomic read |
|
||||
| TXHEAD | 64 | 1 | atomic read |
|
||||
| TXTAIL | 65 | 1 | atomic write |
|
||||
| RXHEAD | 66 | 1 | atomic write |
|
||||
| RXTAIL | 67 | 1 | atomic read |
|
||||
|
||||
For both sending (`TX`) and receiving (`RX`), there are four
|
||||
registers: `xBUF`, `xDATA`, `xHEAD` and `xTAIL`:
|
||||
For both sending (`TX`) and receiving (`RX`), there are three
|
||||
registers: `xBUF`, `xHEAD` and `xTAIL`:
|
||||
|
||||
- `xBUF` registers are 32-byte FIFO ring buffers used for data
|
||||
- The `xDATA` registers indicate whether data is available (0 for
|
||||
data, FFh for no data)
|
||||
- The `xHEAD` and `xTAIL` registers specify the start and end of
|
||||
data in the FIFO, `xHEAD` being the offset of the first byte of
|
||||
data, and `xTAIL` being the offset of the first byte after the
|
||||
data.
|
||||
- The `xHEAD` and `xTAIL` registers specify the start and end of data
|
||||
in the ring buffer, `xHEAD` being the offset of the first byte of
|
||||
data, and `xTAIL` being the offset of the first byte *after* the data.
|
||||
|
||||
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.
|
||||
|
||||
30
emu.js
30
emu.js
@@ -1,15 +1,13 @@
|
||||
const TXBUF = 0;
|
||||
const RXBUF = 32;
|
||||
const TXDATA = 64;
|
||||
const TXHEAD = 65;
|
||||
const TXTAIL = 66;
|
||||
const RXDATA = 67;
|
||||
const RXHEAD = 68;
|
||||
const RXTAIL = 69;
|
||||
const TXHEAD = 64;
|
||||
const TXTAIL = 65;
|
||||
const RXHEAD = 66;
|
||||
const RXTAIL = 67;
|
||||
|
||||
const TXBUF_SIZE = 32;
|
||||
const RXBUF_SIZE = 32;
|
||||
const PERIPHS_SIZE = 70;
|
||||
const PERIPHS_SIZE = 68;
|
||||
|
||||
const POLL_INTERVAL_MS = 20;
|
||||
|
||||
@@ -36,29 +34,21 @@ class Emulator {
|
||||
}
|
||||
|
||||
poll() {
|
||||
const txdata = Atomics.load(this.mem_u8, TXDATA);
|
||||
if (txdata !== 0)
|
||||
this.handle_txdata();
|
||||
const txhead = Atomics.load(this.mem_u8, TXHEAD);
|
||||
const txtail = Atomics.load(this.mem_u8, TXTAIL);
|
||||
if (txhead !== txtail)
|
||||
this.handle_txdata(txhead, txtail);
|
||||
}
|
||||
|
||||
handle_txdata() {
|
||||
const head = Atomics.load(this.mem_u8, TXHEAD);
|
||||
const tail = Atomics.load(this.mem_u8, TXTAIL);
|
||||
|
||||
handle_txdata(head, tail) {
|
||||
const data = [];
|
||||
let i = head;
|
||||
do {
|
||||
data.push(this.mem_u8[TXBUF + i]);
|
||||
i = (i + 1) % TXBUF_SIZE;
|
||||
} while (i !== tail);
|
||||
|
||||
Atomics.store(this.mem_u8, TXHEAD, tail);
|
||||
|
||||
// More data could have been added -- only clear TXDATA if
|
||||
// tail is unchanged.
|
||||
if (tail === Atomics.load(this.mem_u8, TXTAIL))
|
||||
Atomics.store(this.mem_u8, TXDATA, 0);
|
||||
|
||||
const str = this.decoder.decode(new Uint8Array(data));
|
||||
this.output.innerText += str;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user