Compare commits
3 Commits
c99430c75e
...
32c3c6e356
| Author | SHA1 | Date | |
|---|---|---|---|
| 32c3c6e356 | |||
| 2a3949e09f | |||
| 22e477adf7 |
14
README.md
14
README.md
@@ -44,12 +44,12 @@ You could use any HTTP server that sets these headers.
|
|||||||
|
|
||||||
| Name | Address | Size / B | Access |
|
| Name | Address | Size / B | Access |
|
||||||
|--------|---------|----------|--------------|
|
|--------|---------|----------|--------------|
|
||||||
| TXBUF | 0 | 32 | write |
|
| TXBUF | 00h | 32 | write |
|
||||||
| RXBUF | 32 | 32 | read |
|
| RXBUF | 20h | 32 | read |
|
||||||
| TXHEAD | 64 | 1 | atomic read |
|
| TXHEAD | 40h | 4 | atomic read |
|
||||||
| TXTAIL | 65 | 1 | atomic write |
|
| TXTAIL | 44h | 4 | atomic write |
|
||||||
| RXHEAD | 66 | 1 | atomic write |
|
| RXHEAD | 48h | 4 | atomic write |
|
||||||
| RXTAIL | 67 | 1 | atomic read |
|
| RXTAIL | 4Ch | 4 | atomic read |
|
||||||
|
|
||||||
For both sending (`TX`) and receiving (`RX`), there are three
|
For both sending (`TX`) and receiving (`RX`), there are three
|
||||||
registers: `xBUF`, `xHEAD` and `xTAIL`:
|
registers: `xBUF`, `xHEAD` and `xTAIL`:
|
||||||
@@ -67,7 +67,7 @@ unoccupied byte between the tail and the head.
|
|||||||
|
|
||||||
| Name | Address | Size / B | Access |
|
| Name | Address | Size / B | Access |
|
||||||
|----------|---------|----------|--------------|
|
|----------|---------|----------|--------------|
|
||||||
| SYSREADY | 68 | 1 | atomic write |
|
| SYSREADY | 50h | 1 | atomic write |
|
||||||
|
|
||||||
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.
|
||||||
|
|||||||
18
emu.js
18
emu.js
@@ -1,14 +1,14 @@
|
|||||||
const TXBUF = 0;
|
const TXBUF = 0x00;
|
||||||
const RXBUF = 32;
|
const RXBUF = 0x20;
|
||||||
const TXHEAD = 64;
|
const TXHEAD = 0x40;
|
||||||
const TXTAIL = 65;
|
const TXTAIL = 0x44;
|
||||||
const RXHEAD = 66;
|
const RXHEAD = 0x48;
|
||||||
const RXTAIL = 67;
|
const RXTAIL = 0x4c;
|
||||||
const SYSREADY = 68;
|
const SYSREADY = 0x50;
|
||||||
|
|
||||||
const TXBUF_SIZE = 32;
|
const TXBUF_SIZE = 32;
|
||||||
const RXBUF_SIZE = 32;
|
const RXBUF_SIZE = 32;
|
||||||
const PERIPHS_SIZE = 69; // Nice
|
const PERIPHS_SIZE = 81;
|
||||||
|
|
||||||
const POLL_INTERVAL_MS = 20;
|
const POLL_INTERVAL_MS = 20;
|
||||||
|
|
||||||
@@ -27,6 +27,7 @@ class Emulator {
|
|||||||
this.mem_u8 = new Uint8Array(this.mem.buffer);
|
this.mem_u8 = new Uint8Array(this.mem.buffer);
|
||||||
for (let i = 0; i < PERIPHS_SIZE; ++i)
|
for (let i = 0; i < PERIPHS_SIZE; ++i)
|
||||||
this.mem_u8[i] = 0;
|
this.mem_u8[i] = 0;
|
||||||
|
this.mem_i32 = new Int32Array(this.mem.buffer);
|
||||||
|
|
||||||
this.decoder = new TextDecoder('utf-8');
|
this.decoder = new TextDecoder('utf-8');
|
||||||
this.encoder = new TextEncoder('utf-8');
|
this.encoder = new TextEncoder('utf-8');
|
||||||
@@ -103,6 +104,7 @@ class Emulator {
|
|||||||
tail = this.fifo_next(tail);
|
tail = this.fifo_next(tail);
|
||||||
} while (this.fifo_next(tail) != head && this.rx_queue.length != 0);
|
} while (this.fifo_next(tail) != head && this.rx_queue.length != 0);
|
||||||
Atomics.store(this.mem_u8, RXTAIL, tail);
|
Atomics.store(this.mem_u8, RXTAIL, tail);
|
||||||
|
Atomics.notify(this.mem_i32, RXTAIL / 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
print(str) {
|
print(str) {
|
||||||
|
|||||||
28
prelude.f
28
prelude.f
@@ -63,18 +63,6 @@
|
|||||||
|
|
||||||
46 EMIT
|
46 EMIT
|
||||||
|
|
||||||
\ Peripheral register addresses
|
|
||||||
|
|
||||||
: TXBUF 0 ;
|
|
||||||
: RXBUF 32 ;
|
|
||||||
: TXHEAD 64 ;
|
|
||||||
: TXTAIL 65 ;
|
|
||||||
: RXHEAD 66 ;
|
|
||||||
: RXTAIL 67 ;
|
|
||||||
: SYSREADY 68 ;
|
|
||||||
|
|
||||||
46 EMIT
|
|
||||||
|
|
||||||
\ Printing utilities
|
\ Printing utilities
|
||||||
|
|
||||||
: CR 10 EMIT ;
|
: CR 10 EMIT ;
|
||||||
@@ -214,6 +202,22 @@ CHAR . EMIT
|
|||||||
|
|
||||||
CHAR . EMIT
|
CHAR . EMIT
|
||||||
|
|
||||||
|
\ Peripheral register addresses
|
||||||
|
|
||||||
|
HEX
|
||||||
|
|
||||||
|
00 CONSTANT TXBUF
|
||||||
|
20 CONSTANT RXBUF
|
||||||
|
40 CONSTANT TXHEAD
|
||||||
|
44 CONSTANT TXTAIL
|
||||||
|
48 CONSTANT RXHEAD
|
||||||
|
4C CONSTANT RXTAIL
|
||||||
|
50 CONSTANT SYSREADY
|
||||||
|
|
||||||
|
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@ <> ;
|
||||||
|
|||||||
25
wipforth.wat
25
wipforth.wat
@@ -8,9 +8,9 @@
|
|||||||
(global $TXBUF i32 (i32.const 0x0000))
|
(global $TXBUF i32 (i32.const 0x0000))
|
||||||
(global $RXBUF i32 (i32.const 0x0020))
|
(global $RXBUF i32 (i32.const 0x0020))
|
||||||
(global $TXHEAD i32 (i32.const 0x0040))
|
(global $TXHEAD i32 (i32.const 0x0040))
|
||||||
(global $TXTAIL i32 (i32.const 0x0041))
|
(global $TXTAIL i32 (i32.const 0x0044))
|
||||||
(global $RXHEAD i32 (i32.const 0x0042))
|
(global $RXHEAD i32 (i32.const 0x0048))
|
||||||
(global $RXTAIL i32 (i32.const 0x0043))
|
(global $RXTAIL i32 (i32.const 0x004c))
|
||||||
|
|
||||||
;; Forth registers
|
;; Forth registers
|
||||||
(global $rsp (mut i32) (i32.const 0))
|
(global $rsp (mut i32) (i32.const 0))
|
||||||
@@ -628,15 +628,24 @@
|
|||||||
;; Serial I/O
|
;; Serial I/O
|
||||||
|
|
||||||
(func $key (local $head i32)
|
(func $key (local $head i32)
|
||||||
;; Wait for RXBUF to be non-empty
|
|
||||||
loop $wait
|
|
||||||
global.get $RXHEAD
|
global.get $RXHEAD
|
||||||
i32.atomic.load8_u
|
i32.atomic.load8_u
|
||||||
local.tee $head
|
local.tee $head
|
||||||
|
|
||||||
|
;; Wait for RXBUF to be non-empty
|
||||||
|
loop $wait (param i32)
|
||||||
global.get $RXTAIL
|
global.get $RXTAIL
|
||||||
i32.atomic.load8_u
|
i32.atomic.load8_u
|
||||||
i32.eq
|
i32.eq
|
||||||
br_if $wait
|
if
|
||||||
|
global.get $RXTAIL
|
||||||
|
local.get $head
|
||||||
|
i64.const -1
|
||||||
|
memory.atomic.wait32
|
||||||
|
|
||||||
|
local.get $head
|
||||||
|
br $wait
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
;; Read byte at head position
|
;; Read byte at head position
|
||||||
@@ -1395,7 +1404,7 @@
|
|||||||
;;
|
;;
|
||||||
;; DUP DUP 65 >= SWAP 90 <= AND \ Test if A-Z
|
;; DUP DUP 65 >= SWAP 90 <= AND \ Test if A-Z
|
||||||
;; 0BRANCH [60] \ Jump to invalid digit if not
|
;; 0BRANCH [60] \ Jump to invalid digit if not
|
||||||
;; 45 - \ Get digit value
|
;; 55 - \ Get digit value
|
||||||
;;
|
;;
|
||||||
;; DUP DUP 0>= SWAP BASE @ < AND \ Test if 0 <= value < BASE
|
;; DUP DUP 0>= SWAP BASE @ < AND \ Test if 0 <= value < BASE
|
||||||
;; 0BRANCH [8] \ Jump to invalid digit if not
|
;; 0BRANCH [8] \ Jump to invalid digit if not
|
||||||
@@ -1438,7 +1447,7 @@
|
|||||||
"\b4\04\00\00" ;; 0BRANCH
|
"\b4\04\00\00" ;; 0BRANCH
|
||||||
"\3c\00\00\00" ;; 60
|
"\3c\00\00\00" ;; 60
|
||||||
"\18\04\00\00" ;; LIT
|
"\18\04\00\00" ;; LIT
|
||||||
"\2d\00\00\00" ;; 45
|
"\37\00\00\00" ;; 55
|
||||||
"\cc\02\00\00" ;; -
|
"\cc\02\00\00" ;; -
|
||||||
"\08\02\00\00" ;; DUP
|
"\08\02\00\00" ;; DUP
|
||||||
"\08\02\00\00" ;; DUP
|
"\08\02\00\00" ;; DUP
|
||||||
|
|||||||
Reference in New Issue
Block a user