From d11805cd6ca79084f022ff403d307e60d27694a6 Mon Sep 17 00:00:00 2001 From: Camden Dixie O'Brien Date: Tue, 24 Feb 2026 15:53:43 +0000 Subject: [PATCH] Rejig serial periph --- README.md | 27 +++++++++++++-------------- emu.js | 30 ++++++++++-------------------- 2 files changed, 23 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 31e030e..d5d8e84 100644 --- a/README.md +++ b/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. diff --git a/emu.js b/emu.js index 79a652a..eabf3bf 100644 --- a/emu.js +++ b/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; }