Compare commits
6 Commits
main
...
c825146c28
| Author | SHA1 | Date | |
|---|---|---|---|
| c825146c28 | |||
| 6ddf643787 | |||
| 399234677d | |||
| d1bcb86c68 | |||
| a88bbfda12 | |||
| e7c041eeb2 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,2 @@
|
|||||||
out
|
out
|
||||||
build.ninja
|
build.ninja
|
||||||
attic/jotblk/env
|
|
||||||
|
|||||||
@ -1,19 +0,0 @@
|
|||||||
# This file specifies files that are *not* uploaded to Google Cloud
|
|
||||||
# using gcloud. It follows the same syntax as .gitignore, with the addition of
|
|
||||||
# "#!include" directives (which insert the entries of the given .gitignore-style
|
|
||||||
# file at that point).
|
|
||||||
#
|
|
||||||
# For more information, run:
|
|
||||||
# $ gcloud topic gcloudignore
|
|
||||||
#
|
|
||||||
.gcloudignore
|
|
||||||
# If you would like to upload your .git directory, .gitignore file or files
|
|
||||||
# from your .gitignore file, remove the corresponding line
|
|
||||||
# below:
|
|
||||||
.git
|
|
||||||
.gitignore
|
|
||||||
|
|
||||||
# Python pycache:
|
|
||||||
__pycache__/
|
|
||||||
# Ignored by the build system
|
|
||||||
/setup.cfg
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
all:
|
|
||||||
./run.sh
|
|
||||||
|
|
||||||
deploy:
|
|
||||||
gcloud app deploy -q --project jotblk *.yaml
|
|
||||||
|
|
||||||
setup:
|
|
||||||
python3 -m venv env
|
|
||||||
env/bin/pip install -r requirements.txt
|
|
||||||
|
|
||||||
datastore:
|
|
||||||
echo "Run: . dstore.sh"
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
# jotblk
|
|
||||||
|
|
||||||
A web based block based editor to run on AppEngine.
|
|
||||||
|
|
||||||
To run you need the AppEngine SDK.
|
|
||||||
|
|
||||||
To setup run:
|
|
||||||
```
|
|
||||||
make setup
|
|
||||||
```
|
|
||||||
|
|
||||||
In parallel run (for the datastore):
|
|
||||||
```
|
|
||||||
. dstore.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
And separately (to run a webserver on http://localhost:8080):
|
|
||||||
```
|
|
||||||
./run.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
Before use, type password. Default is: xyzzy
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
runtime: python39
|
|
||||||
|
|
||||||
default_expiration: "10m"
|
|
||||||
|
|
||||||
handlers:
|
|
||||||
- url: /
|
|
||||||
static_files: static/index.html
|
|
||||||
upload: static/index.html
|
|
||||||
secure: always
|
|
||||||
|
|
||||||
- url: /static
|
|
||||||
static_dir: static
|
|
||||||
secure: always
|
|
||||||
|
|
||||||
- url: /io
|
|
||||||
script: main.app
|
|
||||||
secure: always
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
# Run this to start an datastore emulator.
|
|
||||||
gcloud emulators firestore start --database-mode=datastore-mode --project=jotblk --host-port=127.0.0.1:8099
|
|
||||||
@ -1,81 +0,0 @@
|
|||||||
# Copyright 2025 Bradley D. Nelson
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
import base64
|
|
||||||
from flask import Flask, request, send_from_directory
|
|
||||||
from google.cloud import datastore
|
|
||||||
|
|
||||||
client = datastore.Client()
|
|
||||||
|
|
||||||
root_passwd_key = client.key('passwd', 'root')
|
|
||||||
root_passwd_entity = client.get(root_passwd_key)
|
|
||||||
if root_passwd_entity is None:
|
|
||||||
root_passwd = 'xyzzy'
|
|
||||||
else:
|
|
||||||
root_passwd = root_passwd_entity['secret']
|
|
||||||
|
|
||||||
def SaveBlock(index, data):
|
|
||||||
assert index >= 0
|
|
||||||
assert len(data) == 1024, len(data)
|
|
||||||
entity = datastore.Entity(key=client.key('block', index+1))
|
|
||||||
entity.update({'data': data})
|
|
||||||
client.put(entity)
|
|
||||||
return ''
|
|
||||||
|
|
||||||
def LoadBlocks(start, end):
|
|
||||||
assert end >= end
|
|
||||||
assert start >= 0
|
|
||||||
assert end - start <= 128
|
|
||||||
query = client.query(kind='block')
|
|
||||||
first_key = client.key('block', start+1)
|
|
||||||
last_key = client.key('block', end+1)
|
|
||||||
query.key_filter(first_key, '>=')
|
|
||||||
query.key_filter(last_key, '<')
|
|
||||||
entities = query.fetch()
|
|
||||||
blks = {}
|
|
||||||
for i in entities:
|
|
||||||
blks[i.key.path[0]['id']-1] = i['data']
|
|
||||||
result = []
|
|
||||||
for i in range(start, end+1):
|
|
||||||
if i in blks:
|
|
||||||
result.append(blks[i])
|
|
||||||
else:
|
|
||||||
result.append(b' ' * 1024)
|
|
||||||
return b''.join(result)
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
|
||||||
|
|
||||||
@app.route('/<path:filename>')
|
|
||||||
def canned(filename):
|
|
||||||
return send_from_directory('static', filename)
|
|
||||||
|
|
||||||
@app.route('/')
|
|
||||||
def root():
|
|
||||||
return canned('index.html')
|
|
||||||
|
|
||||||
@app.route('/io', methods=['POST'])
|
|
||||||
def io():
|
|
||||||
if root_passwd != request.form['passwd']:
|
|
||||||
return 'deny', 403
|
|
||||||
if request.form['command'] == 'read':
|
|
||||||
start = int(request.form['start'])
|
|
||||||
end = int(request.form['end'])
|
|
||||||
return LoadBlocks(start, end)
|
|
||||||
elif request.form['command'] == 'write':
|
|
||||||
index = int(request.form['index'])
|
|
||||||
data = request.files['data'].read()
|
|
||||||
return SaveBlock(index, data)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
app.run(host='127.0.0.1', port=8080, debug=True)
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
Flask==3.0.0
|
|
||||||
google-cloud-datastore==2.15.1
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
#! /bin/bash
|
|
||||||
|
|
||||||
export DATASTORE_DATASET=jotblk
|
|
||||||
export DATASTORE_EMULATOR_HOST=127.0.0.1:8099
|
|
||||||
export DATASTORE_EMULATOR_HOST_PATH=127.0.0.1:8099/datastore
|
|
||||||
export DATASTORE_HOST=http://127.0.0.1:8099
|
|
||||||
export DATASTORE_PROJECT_ID=jotblk
|
|
||||||
env/bin/python3 main.py
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<body>
|
|
||||||
<script src="jotblk.js"></script>
|
|
||||||
@ -1,570 +0,0 @@
|
|||||||
// Copyright 2025 Bradley D. Nelson
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const MAX_BLOCKS = 16 * 1024;
|
|
||||||
const SYNC_CHUNK = 64;
|
|
||||||
const DIRTY = 1;
|
|
||||||
const LOADED = 2;
|
|
||||||
var blocks = new Uint8Array(1024 * MAX_BLOCKS);
|
|
||||||
var flags = new Uint8Array(MAX_BLOCKS);
|
|
||||||
var clipboard = [];
|
|
||||||
var screen_history = [];
|
|
||||||
var keymap = {};
|
|
||||||
var scr = 0;
|
|
||||||
var pos = 0;
|
|
||||||
var marker = 0;
|
|
||||||
var passwd = '';
|
|
||||||
var ForthKeyDown = null;
|
|
||||||
var ForthKeyPress = null;
|
|
||||||
var forth_added = false;
|
|
||||||
var ueforth = null;
|
|
||||||
|
|
||||||
document.body.style.overflow = 'hidden';
|
|
||||||
document.body.style.margin = '0';
|
|
||||||
document.body.style.border = '0';
|
|
||||||
document.body.style.padding = '0';
|
|
||||||
var canvas = document.createElement('canvas');
|
|
||||||
document.body.appendChild(canvas);
|
|
||||||
var ctx = canvas.getContext('2d');
|
|
||||||
|
|
||||||
function SpaceIt() {
|
|
||||||
if (!(flags[scr] & LOADED)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (blocks[scr * 1024] == 0) {
|
|
||||||
for (var i = 0; i < 1024; ++i) {
|
|
||||||
blocks[i + scr * 1024] = 32;
|
|
||||||
}
|
|
||||||
flags[scr] |= DIRTY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function IsEmpty(n) {
|
|
||||||
for (var i = 0; i < 1024; i++) {
|
|
||||||
var ch = blocks[i + n * 1024];
|
|
||||||
if (ch != 32 && ch != 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function FindEnd() {
|
|
||||||
var i = pos;
|
|
||||||
while (i < 1023 &&
|
|
||||||
(blocks[scr * 1024 + i] != 32 ||
|
|
||||||
blocks[scr * 1024 + i + 1] != 32)) {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Insert() {
|
|
||||||
var end = FindEnd();
|
|
||||||
for (var i = end; i >= pos; i--) {
|
|
||||||
blocks[scr * 1024 + i + 1] = blocks[scr * 1024 + i];
|
|
||||||
}
|
|
||||||
blocks[scr * 1024 + pos] = 32;
|
|
||||||
flags[scr] |= DIRTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Delete() {
|
|
||||||
var end = FindEnd();
|
|
||||||
for (var i = pos; i < end; i++) {
|
|
||||||
blocks[scr * 1024 + i] = blocks[scr * 1024 + i + 1];
|
|
||||||
}
|
|
||||||
flags[scr] |= DIRTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
function FindSpan() {
|
|
||||||
var i = Math.floor(pos / 64) * 64;
|
|
||||||
var min = 63;
|
|
||||||
var max = 0;
|
|
||||||
for (var j = 0; j < 64; j++) {
|
|
||||||
if (blocks[scr * 1024 + i + j] != 32) {
|
|
||||||
min = Math.min(min, j);
|
|
||||||
max = Math.max(max, j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (min > max) {
|
|
||||||
return [i, i + 63];
|
|
||||||
}
|
|
||||||
return [i + min, i + max];
|
|
||||||
}
|
|
||||||
|
|
||||||
function Home() {
|
|
||||||
var span = FindSpan();
|
|
||||||
var start = Math.floor(pos / 64) * 64;
|
|
||||||
if (pos == span[0]) {
|
|
||||||
pos = start;
|
|
||||||
} else {
|
|
||||||
pos = span[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function End() {
|
|
||||||
var span = FindSpan();
|
|
||||||
var end = Math.floor(pos / 64) * 64 + 63;
|
|
||||||
var span1 = Math.min(span[1] + 1, end);
|
|
||||||
if (pos == span1) {
|
|
||||||
pos = end;
|
|
||||||
} else {
|
|
||||||
pos = span1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Up() {
|
|
||||||
if (pos >= 64) {
|
|
||||||
pos -= 64;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Down() {
|
|
||||||
if (pos + 64 < 1024) {
|
|
||||||
pos += 64;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Left() {
|
|
||||||
pos = Math.max(0, pos - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function Right() {
|
|
||||||
pos = Math.min(1023, pos + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function Copy() {
|
|
||||||
var row = Math.floor(pos / 64) * 64;
|
|
||||||
clipboard.push(blocks.slice(scr * 1024 + row, scr * 1024 + row + 64));
|
|
||||||
Up();
|
|
||||||
}
|
|
||||||
|
|
||||||
function Cut() {
|
|
||||||
var row = Math.floor(pos / 64) * 64;
|
|
||||||
clipboard.push(blocks.slice(scr * 1024 + row, scr * 1024 + row + 64));
|
|
||||||
for (var j = 0; j < 64; j++) {
|
|
||||||
blocks[scr * 1024 + row + j] = 32;
|
|
||||||
}
|
|
||||||
flags[scr] |= DIRTY;
|
|
||||||
Up();
|
|
||||||
}
|
|
||||||
|
|
||||||
function Paste() {
|
|
||||||
if (clipboard.length == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var row = Math.floor(pos / 64) * 64;
|
|
||||||
var data = clipboard.pop();
|
|
||||||
for (var j = 0; j < 64; j++) {
|
|
||||||
blocks[scr * 1024 + row + j] = data[j];
|
|
||||||
}
|
|
||||||
flags[scr] |= DIRTY;
|
|
||||||
Down();
|
|
||||||
}
|
|
||||||
|
|
||||||
function Update() {
|
|
||||||
SpaceIt();
|
|
||||||
ctx.fillStyle = 'black';
|
|
||||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
||||||
ctx.font = '16px consolas, Monaco, monospace';
|
|
||||||
ctx.textAlign = 'center';
|
|
||||||
ctx.textBaseline = 'middle';
|
|
||||||
ctx.save();
|
|
||||||
ctx.scale(canvas.width / 64 , canvas.height / 17);
|
|
||||||
ctx.fillStyle = '#750';
|
|
||||||
if (window.onkeydown === Login) {
|
|
||||||
ctx.fillRect(10, 0, 1, 1);
|
|
||||||
} else {
|
|
||||||
for (var j = 0; j < 16; ++j) {
|
|
||||||
for (var i = 0; i < 64; ++i) {
|
|
||||||
if (pos === i + j * 64) {
|
|
||||||
ctx.fillRect(i, j, 1, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx.save();
|
|
||||||
var m = ctx.measureText('W');
|
|
||||||
var w = m.width;
|
|
||||||
var h = m.fontBoundingBoxAscent + m.fontBoundingBoxDescent;
|
|
||||||
ctx.scale(1 / w, 1 / h);
|
|
||||||
ctx.fillStyle = '#fb0';
|
|
||||||
if (window.onkeydown === Login) {
|
|
||||||
ctx.fillText('password:', 0.5 * w * 9, 0.5 * h);
|
|
||||||
} else {
|
|
||||||
for (var j = 0; j < 16; ++j) {
|
|
||||||
for (var i = 0; i < 64; ++i) {
|
|
||||||
var ch = String.fromCharCode(blocks[i + j * 64 + scr * 1024]);
|
|
||||||
ctx.fillText(ch, (i + 0.5) * w, (j + 0.5) * h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx.fillStyle = '#750';
|
|
||||||
ctx.textAlign = 'right';
|
|
||||||
var info = '';
|
|
||||||
if (flags[scr] & DIRTY) {
|
|
||||||
info += 'D ';
|
|
||||||
}
|
|
||||||
if (!(flags[scr] & LOADED)) {
|
|
||||||
info += 'L ';
|
|
||||||
}
|
|
||||||
info += scr;
|
|
||||||
ctx.fillText(info, 63.5 * w, 16.5 * h);
|
|
||||||
ctx.restore();
|
|
||||||
ctx.restore();
|
|
||||||
}
|
|
||||||
|
|
||||||
function LoadChunk(n) {
|
|
||||||
if ((flags[n * SYNC_CHUNK] & LOADED)) {
|
|
||||||
return Promise.resolve();
|
|
||||||
} else {
|
|
||||||
return LoadBlocks(n * SYNC_CHUNK, (n + 1) * SYNC_CHUNK).then(function() {
|
|
||||||
Update();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function MaybeLoad() {
|
|
||||||
var s = Math.floor(scr / SYNC_CHUNK);
|
|
||||||
return LoadChunk(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
function LineString(blk, row) {
|
|
||||||
var result = '';
|
|
||||||
for (var col = 0; col < 64; col++) {
|
|
||||||
result += String.fromCharCode(blocks[blk * 1024 + row * 64 + col]);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function BlockString(blk, linebreaks) {
|
|
||||||
var result = '';
|
|
||||||
for (var row = 0; row < 16; row++) {
|
|
||||||
result += LineString(blk, row);
|
|
||||||
if (linebreaks) {
|
|
||||||
result += '\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Eval(n) {
|
|
||||||
eval(BlockString(n, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
function Print() {
|
|
||||||
var start = Math.min(marker, scr);
|
|
||||||
var end = Math.max(marker, scr);
|
|
||||||
var content = '';
|
|
||||||
content += '<!DOCTYPE html>\n';
|
|
||||||
for (var i = start; i <= end; i++) {
|
|
||||||
content += '<pre style="border: 1px solid; display: inline-block;">\n';
|
|
||||||
content += BlockString(i, true).replaceAll('<', '<');
|
|
||||||
content += '<hr/>' + i;
|
|
||||||
content += '</pre><br/>\n';
|
|
||||||
}
|
|
||||||
var blob = new Blob([content], { type: 'text/html' });
|
|
||||||
var url = URL.createObjectURL(blob);
|
|
||||||
window.open(url, '_blank');
|
|
||||||
}
|
|
||||||
|
|
||||||
function Backspace() {
|
|
||||||
if (pos > 0) {
|
|
||||||
--pos;
|
|
||||||
Delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Goto(n) {
|
|
||||||
scr = n;
|
|
||||||
MaybeLoad();
|
|
||||||
}
|
|
||||||
|
|
||||||
function Gosub(n) {
|
|
||||||
screen_history.push(scr);
|
|
||||||
Goto(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
function Adjust(n) {
|
|
||||||
Goto(Math.max(0, Math.min(MAX_BLOCKS - 1, scr + n)));
|
|
||||||
}
|
|
||||||
|
|
||||||
function Enter() {
|
|
||||||
pos = Math.floor((pos + 64) / 64) * 64;
|
|
||||||
if (pos > 1023) {
|
|
||||||
pos -= 64;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function ShiftUp() {
|
|
||||||
pos = (pos % 64);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ShiftDown() {
|
|
||||||
pos = (pos % 64) + 15 * 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
function GetLink() {
|
|
||||||
var s = BlockString(scr, false);
|
|
||||||
var at = s.indexOf('@', pos);
|
|
||||||
var paren = s.indexOf(' )', pos);
|
|
||||||
if (at >= 0 && (at < paren || paren < 0)) {
|
|
||||||
return s.slice(at).split(' ')[0];
|
|
||||||
}
|
|
||||||
if (paren >= 0) {
|
|
||||||
var p2 = s.lastIndexOf('( ', paren);
|
|
||||||
if (p2 >= 0) {
|
|
||||||
return s.slice(p2, paren + 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
function Find(s) {
|
|
||||||
for (var i = 0; i < MAX_BLOCKS; i++) {
|
|
||||||
var j = (scr + 1 + i) % MAX_BLOCKS;
|
|
||||||
if (BlockString(j, false).indexOf(s) >= 0) {
|
|
||||||
return j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function FollowLink() {
|
|
||||||
var link = GetLink();
|
|
||||||
if (link.startsWith('@')) {
|
|
||||||
var n = parseInt(link.slice(1));
|
|
||||||
Gosub(n);
|
|
||||||
} else if (link.startsWith('( ')) {
|
|
||||||
var n = Find(link.slice(2, -2));
|
|
||||||
if (n !== null) {
|
|
||||||
Gosub(n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Type(ch) {
|
|
||||||
Insert();
|
|
||||||
blocks[pos + scr * 1024] = ch;
|
|
||||||
pos = Math.min(1023, pos + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function Key(e) {
|
|
||||||
if (e.ctrlKey && keymap['^' + e.key]) {
|
|
||||||
keymap['^' + e.key](e);
|
|
||||||
} else if (e.shiftKey && keymap['+' + e.key]) {
|
|
||||||
keymap['+' + e.key](e);
|
|
||||||
} else if (keymap[e.key]) {
|
|
||||||
keymap[e.key](e);
|
|
||||||
} else if (e.key.length == 1 && !e.ctrlKey) {
|
|
||||||
Type(e.key.charCodeAt(0));
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Update();
|
|
||||||
e.preventDefault();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Login(e) {
|
|
||||||
if (e.key == 'Backspace') {
|
|
||||||
passwd = passwd.slice(0, -1);
|
|
||||||
} else if (e.key == 'Enter') {
|
|
||||||
window.onkeydown = Key;
|
|
||||||
MaybeLoad().then(function() {
|
|
||||||
Eval(63);
|
|
||||||
});
|
|
||||||
} else if (e.key.length == 1) {
|
|
||||||
passwd += e.key;
|
|
||||||
}
|
|
||||||
Update();
|
|
||||||
e.preventDefault();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Resize() {
|
|
||||||
canvas.width = window.innerWidth;
|
|
||||||
canvas.height = window.innerHeight;
|
|
||||||
Update();
|
|
||||||
}
|
|
||||||
|
|
||||||
function SaveBlock(i) {
|
|
||||||
var fd = new FormData();
|
|
||||||
fd.append('command', 'write');
|
|
||||||
fd.append('passwd', passwd);
|
|
||||||
fd.append('index', i);
|
|
||||||
fd.append('data', new Blob([blocks.slice(i * 1024, (i + 1) * 1024)],
|
|
||||||
{type: "application/octet-stream"}));
|
|
||||||
return fetch('/io', {'method': 'POST', body: fd}).then(function() {
|
|
||||||
flags[i] &= ~DIRTY;
|
|
||||||
Update();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function Sync() {
|
|
||||||
for (var i = 0; i < MAX_BLOCKS; ++i) {
|
|
||||||
if ((flags[i] & LOADED) && (flags[i] & DIRTY)) {
|
|
||||||
SaveBlock(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function FindEmpty() {
|
|
||||||
screen_history.push(scr);
|
|
||||||
while (!IsEmpty(scr)) {
|
|
||||||
Adjust(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function StampLog() {
|
|
||||||
var now = new Date();
|
|
||||||
var month = ('0' + (1 + now.getMonth())).slice(-2);
|
|
||||||
var day = ('0' + now.getDate()).slice(-2);
|
|
||||||
var dt = now.getFullYear() + '-' + month + '-' + day;
|
|
||||||
for (var i = 0; i < dt.length; i++) {
|
|
||||||
blocks[54 + i + scr * 1024] = dt.charCodeAt(i);
|
|
||||||
}
|
|
||||||
var mark = 'LOG: ';
|
|
||||||
for (var i = 0; i < mark.length; i++) {
|
|
||||||
blocks[i + scr * 1024] = mark.charCodeAt(i);
|
|
||||||
}
|
|
||||||
pos = mark.length;
|
|
||||||
flags[scr] |= DIRTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Back() {
|
|
||||||
if (screen_history.length) {
|
|
||||||
Goto(screen_history.pop());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function LoadBlocks(start, end) {
|
|
||||||
var fd = new FormData();
|
|
||||||
fd.append('command', 'read');
|
|
||||||
fd.append('passwd', passwd);
|
|
||||||
fd.append('start', start);
|
|
||||||
fd.append('end', end);
|
|
||||||
return fetch('/io', {'method': 'POST', body: fd}).then(function(response) {
|
|
||||||
if (!response.ok) {
|
|
||||||
throw 'bad fetch';
|
|
||||||
}
|
|
||||||
return response.arrayBuffer().then(function(data) {
|
|
||||||
var u8 = new Uint8Array(data);
|
|
||||||
if (u8.length != (end + 1 - start) * 1024) {
|
|
||||||
throw 'bad load';
|
|
||||||
}
|
|
||||||
for (var i = start; i < end; i++) {
|
|
||||||
if (flags[i] & LOADED) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var dst = i * 1024;
|
|
||||||
var src = (i - start) * 1024;
|
|
||||||
for (var j = 0; j < 1024; j++) {
|
|
||||||
blocks[j + dst] = u8[j + src];
|
|
||||||
}
|
|
||||||
flags[i] |= LOADED;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function ForthKeyFilter(e) {
|
|
||||||
if (e.key == 'f' && e.ctrlKey) {
|
|
||||||
ToggleForth();
|
|
||||||
e.preventDefault();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return ForthKeyDown(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ToggleForth() {
|
|
||||||
if (!forth_added) {
|
|
||||||
forth_added = true;
|
|
||||||
var fscript = document.createElement('script');
|
|
||||||
fscript.src = 'myforth.fs';
|
|
||||||
fscript.type = 'text/forth';
|
|
||||||
document.body.appendChild(fscript);
|
|
||||||
var script = document.createElement('script');
|
|
||||||
script.src = 'https://eforth.appspot.com/ueforth.js';
|
|
||||||
document.body.appendChild(script);
|
|
||||||
function Loader() {
|
|
||||||
if (ueforth !== null) {
|
|
||||||
ueforth.Start();
|
|
||||||
canvas.style.display = 'none';
|
|
||||||
setTimeout(function() {
|
|
||||||
ForthKeyDown = window.onkeydown;
|
|
||||||
ForthKeyPress = window.onkeypress;
|
|
||||||
window.onkeydown = ForthKeyFilter;
|
|
||||||
}, 500);
|
|
||||||
} else {
|
|
||||||
setTimeout(Loader, 10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loader();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (window.onkeydown === Key) {
|
|
||||||
window.onkeydown = ForthKeyFilter;
|
|
||||||
window.onkeypress = ForthKeyPress;
|
|
||||||
canvas.style.display = 'none';
|
|
||||||
ueforth.screen.style.display = '';
|
|
||||||
} else {
|
|
||||||
window.onkeydown = Key;
|
|
||||||
window.onkeypress = null;
|
|
||||||
ueforth.screen.style.display = 'none';
|
|
||||||
canvas.style.display = '';
|
|
||||||
Resize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Init() {
|
|
||||||
keymap['Delete'] = Delete;
|
|
||||||
keymap['Backspace'] = Backspace;
|
|
||||||
keymap['PageUp'] = function() { Adjust(-1); };
|
|
||||||
keymap['PageDown'] = function() { Adjust(1); };
|
|
||||||
keymap['+PageUp'] = function() { Adjust(-16); };
|
|
||||||
keymap['+PageDown'] = function() { Adjust(16); };
|
|
||||||
keymap['Home'] = Home;
|
|
||||||
keymap['End'] = End;
|
|
||||||
keymap['Enter'] = Enter;
|
|
||||||
keymap['^Enter'] = FollowLink;
|
|
||||||
keymap['ArrowUp'] = Up;
|
|
||||||
keymap['ArrowDown'] = Down;
|
|
||||||
keymap['ArrowLeft'] = Left;
|
|
||||||
keymap['ArrowRight'] = Right;
|
|
||||||
keymap['+ArrowUp'] = ShiftUp;
|
|
||||||
keymap['+ArrowDown'] = ShiftDown;
|
|
||||||
keymap['+ArrowLeft'] = Home;
|
|
||||||
keymap['+ArrowRight'] = End;
|
|
||||||
keymap['^c'] = Copy;
|
|
||||||
keymap['^x'] = Cut;
|
|
||||||
keymap['^v'] = Paste;
|
|
||||||
keymap['^m'] = function() { marker = scr; };
|
|
||||||
keymap['^p'] = Print;
|
|
||||||
keymap['^g'] = function() { Eval(scr); };
|
|
||||||
keymap['^o'] = FindEmpty;
|
|
||||||
keymap['^l'] = StampLog;
|
|
||||||
keymap['^b'] = Back;
|
|
||||||
keymap['^f'] = ToggleForth;
|
|
||||||
keymap['^h'] = function() { Gosub(0); };
|
|
||||||
|
|
||||||
window.addEventListener('resize', Resize);
|
|
||||||
window.onkeydown = Login;
|
|
||||||
Resize();
|
|
||||||
}
|
|
||||||
Init();
|
|
||||||
|
|
||||||
setInterval(Sync, 3000);
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
\ Copyright 2021 Bradley D. Nelson
|
|
||||||
\
|
|
||||||
\ Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
\ you may not use this file except in compliance with the License.
|
|
||||||
\ You may obtain a copy of the License at
|
|
||||||
\
|
|
||||||
\ http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
\
|
|
||||||
\ Unless required by applicable law or agreed to in writing, software
|
|
||||||
\ distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
\ See the License for the specific language governing permissions and
|
|
||||||
\ limitations under the License.
|
|
||||||
|
|
||||||
web definitions
|
|
||||||
|
|
||||||
JSWORD: block-read { n a -- }
|
|
||||||
for (var i = 0; i < 1024; i++) {
|
|
||||||
u8[a + i] = blocks[n * 1024 + i];
|
|
||||||
}
|
|
||||||
~
|
|
||||||
|
|
||||||
also internals
|
|
||||||
|
|
||||||
create block-buffer 1024 allot
|
|
||||||
|
|
||||||
also forth definitions
|
|
||||||
|
|
||||||
variable scr
|
|
||||||
: block ( n -- a ) block-buffer block-read block-buffer ;
|
|
||||||
: buffer ( n -- a ) block ;
|
|
||||||
|
|
||||||
only forth definitions
|
|
||||||
|
|
||||||
( Loading )
|
|
||||||
: load ( n -- ) block 1024 evaluate ;
|
|
||||||
: thru ( a b -- ) over - 1+ for aft dup >r load r> 1+ then next drop ;
|
|
||||||
|
|
||||||
( Listing )
|
|
||||||
: list ( n -- ) scr ! ." Block " scr @ . cr scr @ block
|
|
||||||
15 for dup 63 type [char] | emit space 15 r@ - . cr 64 + next drop ;
|
|
||||||
|
|
||||||
only forth definitions
|
|
||||||
@ -42,6 +42,7 @@ CFLAGS_MINIMIZE = [
|
|||||||
'-s',
|
'-s',
|
||||||
'-DUEFORTH_MINIMAL',
|
'-DUEFORTH_MINIMAL',
|
||||||
'-fno-exceptions',
|
'-fno-exceptions',
|
||||||
|
'-ffreestanding',
|
||||||
'-fno-stack-protector',
|
'-fno-stack-protector',
|
||||||
'-fomit-frame-pointer',
|
'-fomit-frame-pointer',
|
||||||
'-fno-ident',
|
'-fno-ident',
|
||||||
@ -135,7 +136,7 @@ def DetectWindowsTools(args):
|
|||||||
sys.stderr.write('Windows %LOCALAPPDATA% not available, Windows support disabled.\n')
|
sys.stderr.write('Windows %LOCALAPPDATA% not available, Windows support disabled.\n')
|
||||||
return
|
return
|
||||||
LOCALAPPDATA = LOCALAPPDATAR.replace('C:/', '/mnt/c/')
|
LOCALAPPDATA = LOCALAPPDATAR.replace('C:/', '/mnt/c/')
|
||||||
ARDUINO_CLI = LSQ(LOCALAPPDATA + '/Programs/*rduino*/resources/app/lib/backend/resources/arduino-cli.exe')
|
ARDUINO_CLI = LOCALAPPDATA + '/Programs/arduino-ide/resources/app/lib/backend/resources/arduino-cli.exe'
|
||||||
WINTMP = LOCALAPPDATA + '/Temp'
|
WINTMP = LOCALAPPDATA + '/Temp'
|
||||||
WINTMPR = LOCALAPPDATAR + '/Temp'
|
WINTMPR = LOCALAPPDATAR + '/Temp'
|
||||||
PROGFILES = '/mnt/c/Program Files'
|
PROGFILES = '/mnt/c/Program Files'
|
||||||
|
|||||||
@ -76,7 +76,7 @@ ESP32_ZIP_FILES += [
|
|||||||
|
|
||||||
# Zip it.
|
# Zip it.
|
||||||
ESP32_FILES += [
|
ESP32_FILES += [
|
||||||
Zip('$dst/esp32/ESP32forth.zip', ESP32_ZIP_FILES, base='$dst/esp32'),
|
Zip('$dst/esp32/ESP32forth.zip', ESP32_ZIP_FILES, base='$dst/esp32/ESP32forth'),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Simulator.
|
# Simulator.
|
||||||
|
|||||||
@ -35,7 +35,7 @@ static Adafruit_SSD1306 *oled_display = 0;
|
|||||||
YV(oled, OledNew, oled_display = new Adafruit_SSD1306(n2, n1, &Wire, n0); DROPn(3)) \
|
YV(oled, OledNew, oled_display = new Adafruit_SSD1306(n2, n1, &Wire, n0); DROPn(3)) \
|
||||||
YV(oled, OledDelete, delete oled_display) \
|
YV(oled, OledDelete, delete oled_display) \
|
||||||
YV(oled, OledBegin, n0 = oled_display->begin(n1, n0); NIP) \
|
YV(oled, OledBegin, n0 = oled_display->begin(n1, n0); NIP) \
|
||||||
YV(oled, OledHOME, oled_display->setCursor(0, 0)) \
|
YV(oled, OledHOME, oled_display->setCursor(0,0); DROP) \
|
||||||
YV(oled, OledCLS, oled_display->clearDisplay()) \
|
YV(oled, OledCLS, oled_display->clearDisplay()) \
|
||||||
YV(oled, OledTextc, oled_display->setTextColor(n0); DROP) \
|
YV(oled, OledTextc, oled_display->setTextColor(n0); DROP) \
|
||||||
YV(oled, OledPrintln, oled_display->println(c0); DROP) \
|
YV(oled, OledPrintln, oled_display->println(c0); DROP) \
|
||||||
@ -45,14 +45,14 @@ static Adafruit_SSD1306 *oled_display = 0;
|
|||||||
YV(oled, OledPrint, oled_display->write(c0); DROP) \
|
YV(oled, OledPrint, oled_display->write(c0); DROP) \
|
||||||
YV(oled, OledInvert, oled_display->invertDisplay(n0); DROP) \
|
YV(oled, OledInvert, oled_display->invertDisplay(n0); DROP) \
|
||||||
YV(oled, OledTextsize, oled_display->setTextSize(n0); DROP) \
|
YV(oled, OledTextsize, oled_display->setTextSize(n0); DROP) \
|
||||||
YV(oled, OledSetCursor, oled_display->setCursor(n1, n0); DROPn(2)) \
|
YV(oled, OledSetCursor, oled_display->setCursor(n1,n0); DROPn(2)) \
|
||||||
YV(oled, OledPixel, oled_display->drawPixel(n2, n1, n0); DROPn(3)) \
|
YV(oled, OledPixel, oled_display->drawPixel(n2, n1, n0); DROPn(2)) \
|
||||||
YV(oled, OledDrawL, oled_display->drawLine(n4, n3, n2, n1, n0); DROPn(5)) \
|
YV(oled, OledDrawL, oled_display->drawLine(n4, n3, n2, n1, n0); DROPn(4)) \
|
||||||
YV(oled, OledCirc, oled_display->drawCircle(n3, n2, n1, n0); DROPn(4)) \
|
YV(oled, OledCirc, oled_display->drawCircle(n3,n2, n1, n0); DROPn(3)) \
|
||||||
YV(oled, OledCircF, oled_display->fillCircle(n3, n2, n1, n0); DROPn(4)) \
|
YV(oled, OledCircF, oled_display->fillCircle(n3, n2, n1, n0); DROPn(3)) \
|
||||||
YV(oled, OledRect, oled_display->drawRect(n4, n3, n2, n1, n0); DROPn(5)) \
|
YV(oled, OledRect, oled_display->drawRect(n4, n3, n2, n1, n0); DROPn(4)) \
|
||||||
YV(oled, OledRectF, oled_display->fillRect(n4, n3, n2, n1, n0); DROPn(5)) \
|
YV(oled, OledRectF, oled_display->fillRect(n4, n3, n2, n1, n0); DROPn(3)) \
|
||||||
YV(oled, OledRectR, oled_display->drawRoundRect(n5, n4, n3, n2, n1, n0); DROPn(6)) \
|
YV(oled, OledRectR, oled_display->drawRoundRect(n5, n4, n3, n2, n1, n0); DROPn(5)) \
|
||||||
YV(oled, OledRectRF, oled_display->fillRoundRect(n5, n4, n3, n2, n1, n0); DROPn(6))
|
YV(oled, OledRectRF, oled_display->fillRoundRect(n5, n4, n3, n2, n1, n0 ); DROPn(5))
|
||||||
|
|
||||||
#include "gen/esp32_oled.h"
|
#include "gen/esp32_oled.h"
|
||||||
|
|||||||
@ -1,44 +0,0 @@
|
|||||||
\ Copyright 2025 Bradley D. Nelson
|
|
||||||
\
|
|
||||||
\ Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
\ you may not use this file except in compliance with the License.
|
|
||||||
\ You may obtain a copy of the License at
|
|
||||||
\
|
|
||||||
\ http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
\
|
|
||||||
\ Unless required by applicable law or agreed to in writing, software
|
|
||||||
\ distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
\ See the License for the specific language governing permissions and
|
|
||||||
\ limitations under the License.
|
|
||||||
|
|
||||||
vocabulary flyclasses flyclasses definitions
|
|
||||||
|
|
||||||
0 value classes
|
|
||||||
1 value methods
|
|
||||||
0 value dispatch
|
|
||||||
0 value implementing
|
|
||||||
|
|
||||||
: flyclass create classes , 1 +to classes does> @ ;
|
|
||||||
: method& ( m cls -- a ) classes mod methods * + cells dispatch + ;
|
|
||||||
: accrued ( -- a ) 0 implementing method& ;
|
|
||||||
: method create methods , 1 +to methods does> @ over method& @ execute ;
|
|
||||||
: implementation ( cls -- ) to implementing ;
|
|
||||||
: >min ( a -- n ) cell+ @ ; : >max ( a -- a ) @ ;
|
|
||||||
: >below ( a -- a ) 2 cells + @ ; : >above ( a -- a) 3 cells + @ ;
|
|
||||||
: field ( min max -- "name" )
|
|
||||||
create 2dup , , accrued @ , swap - 1+ accrued @ * dup , accrued !
|
|
||||||
does> >r r@ >above mod r@ >below / r> >min + ;
|
|
||||||
: doput ( n o -- o "name" ) >r dup r@ >below mod swap r@ >above / r@ >above * +
|
|
||||||
swap r@ >max min r@ >min - r> >below * + ;
|
|
||||||
: put ( n o -- o "name" ) ' >body postpone literal postpone doput ; immediate
|
|
||||||
: extension ( cls -- ) 0 swap method& accrued methods cells cmove ;
|
|
||||||
: initiate here to dispatch
|
|
||||||
classes 1- for classes , methods 1- 1- for ['] abort , next next ;
|
|
||||||
: do:: ( o cls m -- ) swap method& @ execute ;
|
|
||||||
: :: ( o cls "name" -- ) ' >body @ postpone literal postpone do:: ; immediate
|
|
||||||
: m: ' >body @ :noname ;
|
|
||||||
: ;m postpone ; swap implementing method& ! ; immediate
|
|
||||||
|
|
||||||
forth definitions
|
|
||||||
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
\ Copyright 2025 Bradley D. Nelson
|
|
||||||
\
|
|
||||||
\ Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
\ you may not use this file except in compliance with the License.
|
|
||||||
\ You may obtain a copy of the License at
|
|
||||||
\
|
|
||||||
\ http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
\
|
|
||||||
\ Unless required by applicable law or agreed to in writing, software
|
|
||||||
\ distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
\ See the License for the specific language governing permissions and
|
|
||||||
\ limitations under the License.
|
|
||||||
|
|
||||||
needs ice40_synthesis.fs
|
|
||||||
needs ice40_storage.fs
|
|
||||||
@ -1,72 +0,0 @@
|
|||||||
\ Copyright 2025 Bradley D. Nelson
|
|
||||||
\
|
|
||||||
\ Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
\ you may not use this file except in compliance with the License.
|
|
||||||
\ You may obtain a copy of the License at
|
|
||||||
\
|
|
||||||
\ http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
\
|
|
||||||
\ Unless required by applicable law or agreed to in writing, software
|
|
||||||
\ distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
\ See the License for the specific language governing permissions and
|
|
||||||
\ limitations under the License.
|
|
||||||
|
|
||||||
needs ice40_layout.fs
|
|
||||||
|
|
||||||
ice40 synthesis definitions
|
|
||||||
|
|
||||||
1 value tx
|
|
||||||
1 value ty
|
|
||||||
0 value tb
|
|
||||||
|
|
||||||
: PLACE ( x y -- ) to ty to tx 0 to tb ;
|
|
||||||
: PLACE-OUTPUT ( -- o ) tx ty tb Output .create ;
|
|
||||||
: USED? ( -- f ) place-output .isLogic? 0= if -1 exit then
|
|
||||||
place-output .getLogic 0<> ;
|
|
||||||
|
|
||||||
: ADVANCE
|
|
||||||
tb 7 < if 1 +to tb exit then
|
|
||||||
ty cells-height 1- < if 1 +to ty 0 to tb exit then
|
|
||||||
tx cells-width 1- < assert
|
|
||||||
1 +to tx 0 to ty 0 to tb
|
|
||||||
;
|
|
||||||
|
|
||||||
: allot-lut ( -- o )
|
|
||||||
begin used? while
|
|
||||||
advance
|
|
||||||
repeat
|
|
||||||
place-output
|
|
||||||
;
|
|
||||||
|
|
||||||
: ROUTE! { src dst -- }
|
|
||||||
src dst route 0= if
|
|
||||||
." ERROR UNABLE TO ROUTE!!!" cr
|
|
||||||
." SOURCE: " src .print cr
|
|
||||||
." DESTINATION: " dst .print cr
|
|
||||||
123 throw
|
|
||||||
then
|
|
||||||
src dst route.
|
|
||||||
;
|
|
||||||
|
|
||||||
: LUT4 { i0 i1 i2 i3 tbl -- o }
|
|
||||||
allot-lut { o }
|
|
||||||
tbl o .setLogic
|
|
||||||
i0 0 o .getInput route!
|
|
||||||
i1 1 o .getInput route!
|
|
||||||
i2 2 o .getInput route!
|
|
||||||
i3 3 o .getInput route!
|
|
||||||
o
|
|
||||||
;
|
|
||||||
|
|
||||||
: FFL ( -- o )
|
|
||||||
allot-lut { o }
|
|
||||||
$aaaa o .setLogic
|
|
||||||
-1 o .dffEnableBit .setBit
|
|
||||||
o
|
|
||||||
;
|
|
||||||
|
|
||||||
: FF! ( v ff -- ) 0 swap .getInput route! ;
|
|
||||||
|
|
||||||
forth definitions
|
|
||||||
|
|
||||||
@ -1,65 +0,0 @@
|
|||||||
\ Copyright 2025 Bradley D. Nelson
|
|
||||||
\
|
|
||||||
\ Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
\ you may not use this file except in compliance with the License.
|
|
||||||
\ You may obtain a copy of the License at
|
|
||||||
\
|
|
||||||
\ http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
\
|
|
||||||
\ Unless required by applicable law or agreed to in writing, software
|
|
||||||
\ distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
\ See the License for the specific language governing permissions and
|
|
||||||
\ limitations under the License.
|
|
||||||
|
|
||||||
vocabulary ice40 ice40 definitions
|
|
||||||
|
|
||||||
( For the 5k model in the pico-ice )
|
|
||||||
|
|
||||||
26 constant cells-width
|
|
||||||
32 constant cells-height
|
|
||||||
6 constant bram-column1
|
|
||||||
19 constant bram-column2
|
|
||||||
|
|
||||||
692 constant cram-bank-width
|
|
||||||
336 constant cram-height-lower
|
|
||||||
176 constant cram-height-upper
|
|
||||||
cram-height-lower cram-height-upper + constant cram-height
|
|
||||||
cram-bank-width 2* cram-height * 8 / constant cram-size
|
|
||||||
|
|
||||||
160 constant bram-width-lower
|
|
||||||
80 constant bram-width-upper
|
|
||||||
256 constant bram-bank-height
|
|
||||||
128 constant bram-chunk-size
|
|
||||||
|
|
||||||
( For the SG48 package in the pico-ice )
|
|
||||||
48 constant pinmax pinmax 1+ 2* cells constant pinsize
|
|
||||||
create pinmap pinsize allot pinmap pinsize 0 fill
|
|
||||||
0 value pinpos : x 1 +to pinpos ; : p ( p# -- ) pinpos swap cells pinmap + ! x ;
|
|
||||||
: pin#s ( p# -- x y b ) cells pinmap + @ 24 /mod >r 1+ r> 2 /mod 1 xor 31 * swap ;
|
|
||||||
\ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 COLUMN
|
|
||||||
\ | | | | | | | | | | | | | | | | | | | | | | | |
|
|
||||||
x x x 39 p 40 p 41 p x 42 p 43 p x x x 37 p x x 32 p 28 p 26 p 23 p x x x x x \ 0 TOP
|
|
||||||
x x x x x x x 38 p 36 p x x 35 p 34 p x x 31 p x 27 p 25 p x x x x x \ 1
|
|
||||||
\ | | | | | | | | | | | | | | | | | | | | | | | | PIN#
|
|
||||||
x x x x 46 p 47 p 48 p 2 p 4 p x x x x x 9 p 10 p 11 p 12 p 13 p x x x 14 p 15 p \ 0
|
|
||||||
x x x x x 44 p 45 p x 3 p x x x 6 p x x x x 21 p 20 p x 19 p 18 p 17 p 16 p \ 1 BOT
|
|
||||||
|
|
||||||
( Whole bitmap for config ram )
|
|
||||||
cram-size allocate throw constant cram
|
|
||||||
cram cram-size 0 fill
|
|
||||||
|
|
||||||
( Clear, read, and write as a bitmap )
|
|
||||||
: clear cram cram-size 0 fill ;
|
|
||||||
: cr& ( x y -- a*8 ) cram-height-lower /mod if
|
|
||||||
cram-height-upper 1- swap - cram-height-lower +
|
|
||||||
then cram-bank-width * >r
|
|
||||||
cram-bank-width 2 - /mod if
|
|
||||||
cram-bank-width 1- swap - 2 - cram-bank-width cram-height * +
|
|
||||||
then r> + ;
|
|
||||||
: bit! ( b pos v -- v ) >r 1 swap 7 swap - lshift dup invert r> and >r swap 0<> and r> or ;
|
|
||||||
: cram! ( b x y -- ) cr& 8 /mod cram + dup >r c@ bit! r> c! ;
|
|
||||||
: cram@ ( x y -- b ) cr& 8 /mod cram + c@ swap 7 swap - rshift 1 and 0<> ; ( UNTESTED )
|
|
||||||
|
|
||||||
forth definitions
|
|
||||||
|
|
||||||
@ -1,795 +0,0 @@
|
|||||||
\ Copyright 2025 Bradley D. Nelson
|
|
||||||
\
|
|
||||||
\ Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
\ you may not use this file except in compliance with the License.
|
|
||||||
\ You may obtain a copy of the License at
|
|
||||||
\
|
|
||||||
\ http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
\
|
|
||||||
\ Unless required by applicable law or agreed to in writing, software
|
|
||||||
\ distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
\ See the License for the specific language governing permissions and
|
|
||||||
\ limitations under the License.
|
|
||||||
|
|
||||||
needs ice40_config.fs
|
|
||||||
needs flyclasses.fs
|
|
||||||
|
|
||||||
ice40 definitions
|
|
||||||
vocabulary synthesis synthesis definitions
|
|
||||||
also flyclasses
|
|
||||||
|
|
||||||
54 constant logic-width
|
|
||||||
42 constant ram-width
|
|
||||||
logic-width ram-width - constant logicram-diff
|
|
||||||
|
|
||||||
flyclass CramBit
|
|
||||||
flyclass CramCell
|
|
||||||
flyclass Output
|
|
||||||
flyclass Input
|
|
||||||
flyclass Input0
|
|
||||||
flyclass Input1
|
|
||||||
flyclass Input2
|
|
||||||
flyclass Input3
|
|
||||||
flyclass LocalG
|
|
||||||
flyclass LocalG0
|
|
||||||
flyclass LocalG1
|
|
||||||
flyclass LocalG2
|
|
||||||
flyclass LocalG3
|
|
||||||
flyclass IOLocalG
|
|
||||||
flyclass IOLocalG0
|
|
||||||
flyclass IOLocalG1
|
|
||||||
flyclass SpanWire
|
|
||||||
flyclass Sp4HR
|
|
||||||
flyclass Sp4VB
|
|
||||||
flyclass Sp12HR
|
|
||||||
flyclass Sp12VB
|
|
||||||
flyclass IOPin
|
|
||||||
flyclass IOInput
|
|
||||||
flyclass IOOutput
|
|
||||||
flyclass IOOutput0
|
|
||||||
flyclass IOOutput1
|
|
||||||
flyclass IOEnable
|
|
||||||
flyclass IOFabOutput
|
|
||||||
flyclass LUTFFGlobal
|
|
||||||
flyclass FFSetReset
|
|
||||||
flyclass FFClock
|
|
||||||
flyclass FFEnable
|
|
||||||
flyclass GlobalNetwork
|
|
||||||
flyclass NotConnected
|
|
||||||
|
|
||||||
method .create ( <various> o -- o )
|
|
||||||
method .optionCount ( o -- n )
|
|
||||||
method .optionWire ( i o -- wire )
|
|
||||||
method .getOption ( o -- n )
|
|
||||||
method .setOption ( n o -- )
|
|
||||||
method .print ( o -- )
|
|
||||||
|
|
||||||
method .getXY ( o -- x y )
|
|
||||||
method .getBit ( o -- b ) ( overloaded for wires and CramBits )
|
|
||||||
method .setBit ( b o -- )
|
|
||||||
method .inside ( x y o -- o' )
|
|
||||||
method .isLogic? ( o -- f )
|
|
||||||
method .isRam? ( o -- f )
|
|
||||||
method .isIO? ( o -- f )
|
|
||||||
method .isBottom? ( o -- f )
|
|
||||||
method .isInside? ( o -- f )
|
|
||||||
method .listBits ( x o -- )
|
|
||||||
method .enableBit ( o -- bit )
|
|
||||||
method .inputEnableBit ( o -- bit )
|
|
||||||
method .setNoResetBit ( o -- bit )
|
|
||||||
method .asyncResetBit ( o -- bit )
|
|
||||||
method .carryEnableBit ( o -- bit )
|
|
||||||
method .dffEnableBit ( o -- bit )
|
|
||||||
method .setPath ( n o -- )
|
|
||||||
method .getPath ( o -- n )
|
|
||||||
method .getInput ( n o -- wire )
|
|
||||||
method .setLogic ( n o -- )
|
|
||||||
method .getLogic ( o -- n )
|
|
||||||
method .routes ( xt target o -- ) ( xt gets: bit wire )
|
|
||||||
method .walk ( xt o -- ) ( xt gets: bit wire )
|
|
||||||
method .makeOutput ( o -- )
|
|
||||||
method .makeInput ( o -- )
|
|
||||||
method .setPinType ( n o -- )
|
|
||||||
method .getPinType ( o -- n )
|
|
||||||
method .getParity ( o -- n )
|
|
||||||
method .getRow ( o -- n )
|
|
||||||
|
|
||||||
initiate
|
|
||||||
|
|
||||||
CramBit implementation
|
|
||||||
0 cram-bank-width 2* 1- field x
|
|
||||||
0 cram-height 1- field y
|
|
||||||
m: .create ( x y o -- o ) put y put x ;m
|
|
||||||
m: .print { o -- } ." CramBit(" o x . ." , " o y . ." ) " ;m
|
|
||||||
m: .setBit { b o -- } b o x o y cram! ;m
|
|
||||||
m: .getBit { o -- b } o x o y cram@ ;m
|
|
||||||
|
|
||||||
: Sp4RVB { x y i -- o } x 1+ y i Sp4VB .create ;
|
|
||||||
|
|
||||||
: span4_horz { i o -- wire } o .getXY i Sp4HR .create ;
|
|
||||||
: span4_vert { i o -- wire }
|
|
||||||
o .isBottom? if
|
|
||||||
o .getXY 1+ i Sp4VB .create
|
|
||||||
else
|
|
||||||
i 35 > if NotConnected .create exit then
|
|
||||||
o .getXY i Sp4VB .create
|
|
||||||
then ;
|
|
||||||
: span12_vert { i o -- wire }
|
|
||||||
o .isBottom? if
|
|
||||||
o .getXY 1+ i Sp12VB .create
|
|
||||||
else
|
|
||||||
i 21 > if NotConnected .create exit then
|
|
||||||
o .getXY i Sp12VB .create
|
|
||||||
then ;
|
|
||||||
|
|
||||||
CramCell implementation
|
|
||||||
-13 cells-width 13 + 1- field cx
|
|
||||||
-13 cells-height 13 + 1- field cy
|
|
||||||
m: .create ( x y o -- o ) put cy put cx ;m
|
|
||||||
m: .print { o -- } ." CramCell(" o cx . ." , " o cy . ." ) " ;m
|
|
||||||
m: .getXY { o -- cx cy } o cx o cy ;m
|
|
||||||
m: .inside { x y o -- o' } o cx 54 * x +
|
|
||||||
o cx 6 > if logicram-diff - then
|
|
||||||
o cx 19 > if logicram-diff - then
|
|
||||||
o cy 16 * y + CramBit .create ;m
|
|
||||||
m: .isInside? { o -- f } o cx 0 >= o cx cells-width < and
|
|
||||||
o cy 0 >= o cy cells-height < and and ;m
|
|
||||||
m: .isIO? { o -- f } o cx 0 = o cx cells-width 1- = or
|
|
||||||
o cy 0 = or o cy cells-height 1- = or ;m
|
|
||||||
m: .isBottom? { o -- g } o cy 0= ;m
|
|
||||||
m: .isRam? { o -- f } o cx bram-column1 = o cx bram-column2 = or o .isIO? 0= and ;m
|
|
||||||
m: .isLogic? { o -- f } o .isRam? 0= o .isIO? 0= and ;m
|
|
||||||
: route12 { x y i m n target xt o }
|
|
||||||
target i o span12_vert = if
|
|
||||||
x y o .inside o .getXY m n IOInput .create xt execute
|
|
||||||
then ;
|
|
||||||
: route4v { x y i m n target xt o }
|
|
||||||
target i o span4_vert = if
|
|
||||||
x y o .inside o .getXY m n IOInput .create xt execute
|
|
||||||
then ;
|
|
||||||
: route4h { x y i m n target xt o }
|
|
||||||
target i o span4_horz = if
|
|
||||||
x y o .inside o .getXY m n IOInput .create xt execute
|
|
||||||
then ;
|
|
||||||
m: .routes { xt target o -- }
|
|
||||||
o .isIO? if
|
|
||||||
5 1 0 0 0 target xt o route12
|
|
||||||
5 3 8 0 0 target xt o route12
|
|
||||||
5 5 16 0 0 target xt o route12
|
|
||||||
23 0 16 0 0 target xt o route4v
|
|
||||||
23 1 0 0 0 target xt o route4v
|
|
||||||
23 2 40 0 0 target xt o route4v
|
|
||||||
23 3 4 0 0 target xt o route4h
|
|
||||||
25 0 24 0 0 target xt o route4v
|
|
||||||
25 1 8 0 0 target xt o route4v
|
|
||||||
25 2 0 0 0 target xt o route4h
|
|
||||||
25 3 8 0 0 target xt o route4h
|
|
||||||
26 1 32 0 0 target xt o route4v
|
|
||||||
26 2 12 0 0 target xt o route4h
|
|
||||||
|
|
||||||
4 6 2 0 1 target xt o route12
|
|
||||||
5 6 10 0 1 target xt o route12
|
|
||||||
4 7 18 0 1 target xt o route12
|
|
||||||
23 4 18 0 1 target xt o route4v
|
|
||||||
23 5 2 0 1 target xt o route4v
|
|
||||||
23 6 42 0 1 target xt o route4v
|
|
||||||
23 7 5 0 1 target xt o route4h
|
|
||||||
25 4 26 0 1 target xt o route4v
|
|
||||||
25 5 10 0 1 target xt o route4v
|
|
||||||
25 6 1 0 1 target xt o route4h
|
|
||||||
25 7 9 0 1 target xt o route4h
|
|
||||||
26 5 34 0 1 target xt o route4v
|
|
||||||
26 6 13 0 1 target xt o route4h
|
|
||||||
|
|
||||||
4 9 4 1 0 target xt o route12
|
|
||||||
5 9 12 1 0 target xt o route12
|
|
||||||
4 8 20 1 0 target xt o route12
|
|
||||||
23 8 20 1 0 target xt o route4v
|
|
||||||
23 9 4 1 0 target xt o route4v
|
|
||||||
23 10 44 1 0 target xt o route4v
|
|
||||||
23 11 6 1 0 target xt o route4h
|
|
||||||
25 8 28 1 0 target xt o route4v
|
|
||||||
25 9 12 1 0 target xt o route4v
|
|
||||||
25 10 2 1 0 target xt o route4h
|
|
||||||
25 11 10 1 0 target xt o route4h
|
|
||||||
26 9 36 1 0 target xt o route4v
|
|
||||||
26 10 14 1 0 target xt o route4h
|
|
||||||
|
|
||||||
5 10 6 1 1 target xt o route12
|
|
||||||
5 12 14 1 1 target xt o route12
|
|
||||||
5 14 22 1 1 target xt o route12
|
|
||||||
23 12 22 1 1 target xt o route4v
|
|
||||||
23 13 6 1 1 target xt o route4v
|
|
||||||
23 14 46 1 1 target xt o route4v
|
|
||||||
23 15 7 1 1 target xt o route4h
|
|
||||||
25 12 30 1 1 target xt o route4v
|
|
||||||
25 13 14 1 1 target xt o route4v
|
|
||||||
25 14 3 1 1 target xt o route4h
|
|
||||||
25 15 11 1 1 target xt o route4h
|
|
||||||
26 13 38 1 1 target xt o route4v
|
|
||||||
26 13 15 1 1 target xt o route4h
|
|
||||||
exit
|
|
||||||
then
|
|
||||||
o .isInside? 0= if exit then
|
|
||||||
8 0 do
|
|
||||||
target o .getXY i 2* Sp4HR .create = if
|
|
||||||
46 i 2* 1+ o .inside o .getXY i Output .create xt execute
|
|
||||||
then
|
|
||||||
target o .getXY i 2* 16 + Sp4HR .create = if
|
|
||||||
46 i 2* o .inside o .getXY i Output .create xt execute
|
|
||||||
then
|
|
||||||
target o .getXY i 2* 32 + Sp4HR .create = if
|
|
||||||
47 i 2* 1+ o .inside o .getXY i Output .create xt execute
|
|
||||||
then
|
|
||||||
target o .getXY i 2* 1+ Sp4RVB = if
|
|
||||||
52 i 2* 1+ o .inside o .getXY i Output .create xt execute
|
|
||||||
then
|
|
||||||
target o .getXY i 2* 17 + Sp4RVB = if
|
|
||||||
53 i 2* o .inside o .getXY i Output .create xt execute
|
|
||||||
then
|
|
||||||
target o .getXY i 2* 33 + Sp4RVB = if
|
|
||||||
53 i 2* 1+ o .inside o .getXY i Output .create xt execute
|
|
||||||
then
|
|
||||||
loop
|
|
||||||
4 0 do
|
|
||||||
target o .getXY i 2* 8 + Sp12HR .create = if
|
|
||||||
47 i 2* o .inside o .getXY i Output .create xt execute
|
|
||||||
then
|
|
||||||
target o .getXY i 2* Sp12HR .create = if
|
|
||||||
47 i 2* 8 + o .inside o .getXY i 4 + Output .create xt execute
|
|
||||||
then
|
|
||||||
|
|
||||||
target o .getXY i 2* Sp4VB .create = if
|
|
||||||
48 i 2* o .inside o .getXY i Output .create xt execute
|
|
||||||
then
|
|
||||||
target o .getXY i 2* 16 + Sp4VB .create = if
|
|
||||||
48 i 2* 1+ o .inside o .getXY i Output .create xt execute
|
|
||||||
then
|
|
||||||
target o .getXY i 2* 16 + Sp12HR .create = if
|
|
||||||
48 i 2* 8 + o .inside o .getXY i 4 + Output .create xt execute
|
|
||||||
then
|
|
||||||
target o .getXY i 2* 8 + Sp4VB .create = if
|
|
||||||
48 i 2* 1+ 8 + o .inside o .getXY i 4 + Output .create xt execute
|
|
||||||
then
|
|
||||||
|
|
||||||
target o .getXY i 2* Sp12VB .create = if
|
|
||||||
51 i 2* o .inside o .getXY i Output .create xt execute
|
|
||||||
then
|
|
||||||
target o .getXY i 2* 32 + Sp4VB .create = if
|
|
||||||
51 i 2* 1+ o .inside o .getXY i Output .create xt execute
|
|
||||||
then
|
|
||||||
target o .getXY i 2* 40 + Sp4VB .create = if
|
|
||||||
51 i 2* 8 + o .inside o .getXY i 4 + Output .create xt execute
|
|
||||||
then
|
|
||||||
target o .getXY i 2* 24 + Sp4VB .create = if
|
|
||||||
51 i 2* 1+ 8 + o .inside o .getXY i 4 + Output .create xt execute
|
|
||||||
then
|
|
||||||
|
|
||||||
target o .getXY i 2* 16 + Sp12VB .create = if
|
|
||||||
52 i 2* o .inside o .getXY i Output .create xt execute
|
|
||||||
then
|
|
||||||
target o .getXY i 2* 8 + Sp4VB .create = if
|
|
||||||
52 i 2* 8 + o .inside o .getXY i 4 + Output .create xt execute
|
|
||||||
then
|
|
||||||
loop
|
|
||||||
;m
|
|
||||||
|
|
||||||
: getBits { n i w -- n i } n w .getBit 1 and i lshift or i 1+ ;
|
|
||||||
: setBits { n w -- n } n 1 and w .setBit n 2/ ;
|
|
||||||
|
|
||||||
Output implementation CramCell extension
|
|
||||||
0 7 field bit
|
|
||||||
m: .create { cx cy b o -- o } cx cy o CramCell :: .create b swap put bit ;m
|
|
||||||
m: .print { o -- } ." Output(" o .getXY swap . . ." , " o bit . ." ) " ;m
|
|
||||||
m: .getBit ( o -- b ) bit ;m
|
|
||||||
m: .optionCount { o -- n } 0 ;m
|
|
||||||
m: .optionWire ( i o -- wire ) abort ;m
|
|
||||||
m: .setOption ( n o -- ) abort ;m
|
|
||||||
m: .getOption { o -- n } 0 ;m
|
|
||||||
create input_table Input0 , Input1 , Input2 , Input3 ,
|
|
||||||
m: .getInput { n o -- wire } o .getXY o .getBit n cells input_table + @ .create ;m
|
|
||||||
create logic_table $04 c, $14 c, $15 c, $05 c, $06 c, $16 c, $17 c, $07 c,
|
|
||||||
$03 c, $13 c, $12 c, $02 c, $01 c, $11 c, $10 c, $00 c,
|
|
||||||
m: .setLogic { n o -- } n ['] setBits o .listBits drop ;m
|
|
||||||
m: .getLogic { o -- n } 0 0 ['] getBits o .listBits drop ;m
|
|
||||||
m: .listBits { x o -- } 16 0 do
|
|
||||||
i logic_table + c@ 16 /mod >r 36 + r> o .getBit 2* + o .inside x execute
|
|
||||||
loop ;m
|
|
||||||
m: .setNoResetBit { o -- bit } 44 o .getBit 2* 1+ o .inside ;m
|
|
||||||
m: .asyncResetBit { o -- bit } 45 o .getBit 2* 1+ o .inside ;m
|
|
||||||
m: .carryEnableBit { o -- bit } 44 o .getBit 2* o .inside ;m
|
|
||||||
m: .dffEnableBit { o -- bit } 45 o .getBit 2* o .inside ;m
|
|
||||||
|
|
||||||
Input implementation Output extension
|
|
||||||
m: .getPath { o -- n } 0 0 ['] getBits o .listBits drop ;m
|
|
||||||
m: .setPath { n o -- } n ['] setBits o .listBits drop ;m
|
|
||||||
m: .optionCount { o -- n } 17 ;m
|
|
||||||
m: .getOption { o -- n } o .enableBit .getBit if
|
|
||||||
o .getPath 1+
|
|
||||||
else
|
|
||||||
0
|
|
||||||
then ;m
|
|
||||||
m: .setOption { n o -- } n if
|
|
||||||
-1 o .enableBit .setBit
|
|
||||||
n 1- o .setPath
|
|
||||||
else
|
|
||||||
0 o .enableBit .setBit
|
|
||||||
0 o .setPath ( for good measure )
|
|
||||||
then ;m
|
|
||||||
|
|
||||||
: inOptWire { i o lo hi -- wire }
|
|
||||||
i 0= if NotConnected .create exit then
|
|
||||||
i 1- 2 rshift 3 and { rt }
|
|
||||||
o .getXY
|
|
||||||
o .getBit 1 and if hi else lo then rt rshift 1 and i 1- 2* or
|
|
||||||
LocalG .create
|
|
||||||
;
|
|
||||||
|
|
||||||
Input0 implementation Input extension
|
|
||||||
m: .print { o -- } ." Input0(" o .getXY swap . . ." , " o .getBit . ." ) " ;m
|
|
||||||
m: .enableBit { o -- wire } 29 o .getBit 2* 1+ o .inside ;m
|
|
||||||
m: .listBits { x o -- } 26 o .getBit 2* 1+ o .inside x execute
|
|
||||||
26 o .getBit 2* o .inside x execute
|
|
||||||
27 o .getBit 2* 1+ o .inside x execute
|
|
||||||
28 o .getBit 2* 1+ o .inside x execute ;m
|
|
||||||
m: .optionWire ( i o -- wire ) $a $5 inOptWire ;m
|
|
||||||
|
|
||||||
Input1 implementation Input extension
|
|
||||||
m: .print { o -- } ." Input1(" o .getXY swap . . ." , " o .getBit . ." ) " ;m
|
|
||||||
m: .enableBit { o -- wire } 29 o .getBit 2* o .inside ;m
|
|
||||||
m: .listBits { x o -- } 30 o .getBit 2* 1+ o .inside x execute
|
|
||||||
30 o .getBit 2* o .inside x execute
|
|
||||||
27 o .getBit 2* o .inside x execute
|
|
||||||
28 o .getBit 2* o .inside x execute ;m
|
|
||||||
m: .optionWire ( i o -- wire ) $5 $a inOptWire ;m
|
|
||||||
|
|
||||||
Input2 implementation Input extension
|
|
||||||
m: .print { o -- } ." Input2(" o .getXY swap . . ." , " o .getBit . ." ) " ;m
|
|
||||||
m: .enableBit { o -- wire } 32 o .getBit 2* 1+ o .inside ;m
|
|
||||||
m: .listBits { x o -- } 35 o .getBit 2* 1+ o .inside x execute
|
|
||||||
35 o .getBit 2* o .inside x execute
|
|
||||||
34 o .getBit 2* 1+ o .inside x execute
|
|
||||||
33 o .getBit 2* 1+ o .inside x execute ;m
|
|
||||||
m: .optionWire ( i o -- wire ) $a $5 inOptWire ;m
|
|
||||||
|
|
||||||
Input3 implementation Input extension
|
|
||||||
m: .print { o -- } ." Input3(" o .getXY swap . . ." , " o .getBit . ." ) " ;m
|
|
||||||
m: .enableBit { o -- wire } 32 o .getBit 2* o .inside ;m
|
|
||||||
m: .listBits { x o -- } 31 o .getBit 2* 1+ o .inside x execute
|
|
||||||
31 o .getBit 2* o .inside x execute
|
|
||||||
34 o .getBit 2* o .inside x execute
|
|
||||||
33 o .getBit 2* o .inside x execute ;m
|
|
||||||
m: .optionWire ( i o -- wire ) $5 $a inOptWire ;m
|
|
||||||
|
|
||||||
LocalG implementation CramCell extension
|
|
||||||
0 31 field identifier
|
|
||||||
create localg_table LocalG0 , LocalG1 , LocalG2 , LocalG3 ,
|
|
||||||
m: .create { cx cy id o -- o }
|
|
||||||
id 4 mod cells localg_table + @ to o
|
|
||||||
cx cy o CramCell :: .create id swap put identifier ;m
|
|
||||||
m: .print { o -- } ." LocalG(" o .getXY swap . . ." , g" o identifier 8 /mod . . ." ) " ;m
|
|
||||||
m: .getPath { o -- n } 0 0 ['] getBits o .listBits drop ;m
|
|
||||||
m: .setPath { n o -- } n ['] setBits o .listBits drop ;m
|
|
||||||
m: .optionCount { o -- n } 15 ;m
|
|
||||||
m: .getBit { o -- n } o identifier 4 / 8 mod ;m
|
|
||||||
m: .getOption { o -- n } o .enableBit .getBit if
|
|
||||||
o .getPath 1-
|
|
||||||
else
|
|
||||||
0
|
|
||||||
then ;m
|
|
||||||
m: .setOption { n o -- } n if
|
|
||||||
-1 o .enableBit .setBit
|
|
||||||
n 1+ o .setPath
|
|
||||||
else
|
|
||||||
0 o .enableBit .setBit
|
|
||||||
0 o .setPath ( for good measure )
|
|
||||||
then ;m
|
|
||||||
: sp4skew { id off -- n } id 8 mod id 16 >= if 24 + then off + ;
|
|
||||||
: sp12skew { id off -- n cls } id 8 mod off + id 16 >= if Sp12VB else Sp12HR then ;
|
|
||||||
m: .optionWire { i o -- wire }
|
|
||||||
i 0 >= assert i o .optionCount < assert
|
|
||||||
i 0= if NotConnected .create exit then
|
|
||||||
i case
|
|
||||||
( TODO: shift by 2 and add r_v_b )
|
|
||||||
6 of o .getXY o identifier 0 sp12skew .create exit endof
|
|
||||||
7 of o .getXY o identifier 8 sp12skew .create exit endof
|
|
||||||
8 of o .getXY o identifier 16 sp12skew .create exit endof
|
|
||||||
9 of o .getXY o identifier 16 sp4skew Sp4VB .create exit endof
|
|
||||||
10 of o .getXY o identifier 0 sp4skew Sp4HR .create exit endof
|
|
||||||
11 of o .getXY o identifier 0 sp4skew Sp4VB .create exit endof
|
|
||||||
12 of o .getXY o identifier 8 sp4skew Sp4VB .create exit endof
|
|
||||||
13 of o .getXY o identifier 8 sp4skew Sp4HR .create exit endof
|
|
||||||
14 of o .getXY o identifier 16 sp4skew Sp4HR .create exit endof
|
|
||||||
endcase
|
|
||||||
o identifier 16 < if
|
|
||||||
i case
|
|
||||||
1 of 0 -1 endof
|
|
||||||
2 of 0 1 endof
|
|
||||||
3 of 0 0 endof
|
|
||||||
4 of 1 -1 endof
|
|
||||||
5 of -1 0 endof
|
|
||||||
endcase
|
|
||||||
else
|
|
||||||
i case
|
|
||||||
1 of 1 1 endof
|
|
||||||
2 of -1 1 endof
|
|
||||||
3 of 0 0 endof
|
|
||||||
4 of -1 -1 endof
|
|
||||||
5 of 1 0 endof
|
|
||||||
endcase
|
|
||||||
then
|
|
||||||
{ x y }
|
|
||||||
o .getXY y + to y x + to x
|
|
||||||
x 1 < if NotConnected .create exit then
|
|
||||||
x cells-width 1- >= if NotConnected .create exit then
|
|
||||||
y cells-height >= if NotConnected .create exit then
|
|
||||||
y 0< if NotConnected .create exit then
|
|
||||||
x y o identifier 8 mod Output .create
|
|
||||||
;m
|
|
||||||
|
|
||||||
LocalG0 implementation LocalG extension
|
|
||||||
m: .enableBit { o -- wire } 17 o .getBit 2* 1+ o .inside ;m
|
|
||||||
m: .listBits { x o -- } 14 o .getBit 2* 1+ o .inside x execute
|
|
||||||
15 o .getBit 2* 1+ o .inside x execute
|
|
||||||
14 o .getBit 2* o .inside x execute
|
|
||||||
16 o .getBit 2* 1+ o .inside x execute ;m
|
|
||||||
|
|
||||||
LocalG1 implementation LocalG extension
|
|
||||||
m: .enableBit { o -- wire } 17 o .getBit 2* o .inside ;m
|
|
||||||
m: .listBits { x o -- } 18 o .getBit 2* 1+ o .inside x execute
|
|
||||||
15 o .getBit 2* o .inside x execute
|
|
||||||
18 o .getBit 2* o .inside x execute
|
|
||||||
16 o .getBit 2* o .inside x execute ;m
|
|
||||||
|
|
||||||
LocalG2 implementation LocalG extension
|
|
||||||
m: .enableBit { o -- wire } 22 o .getBit 2* 1+ o .inside ;m
|
|
||||||
m: .listBits { x o -- } 25 o .getBit 2* 1+ o .inside x execute
|
|
||||||
24 o .getBit 2* 1+ o .inside x execute
|
|
||||||
25 o .getBit 2* o .inside x execute
|
|
||||||
23 o .getBit 2* 1+ o .inside x execute ;m
|
|
||||||
|
|
||||||
LocalG3 implementation LocalG extension
|
|
||||||
m: .enableBit { o -- wire } 22 o .getBit 2* o .inside ;m
|
|
||||||
m: .listBits { x o -- } 21 o .getBit 2* 1+ o .inside x execute
|
|
||||||
24 o .getBit 2* o .inside x execute
|
|
||||||
21 o .getBit 2* o .inside x execute
|
|
||||||
23 o .getBit 2* o .inside x execute ;m
|
|
||||||
|
|
||||||
create iopermy 0 , 1 , 3 , 2 , 4 , 5 , 7 , 6 , 8 , 9 , 11 , 10 , 12 , 13 , 15 , 14 ,
|
|
||||||
: >iopermy ( n -- n ) cells iopermy + @ ;
|
|
||||||
|
|
||||||
IOLocalG implementation CramCell extension
|
|
||||||
0 15 field identifier
|
|
||||||
create localg_table IOLocalG0 , IOLocalG1 ,
|
|
||||||
m: .create { cx cy id o -- o }
|
|
||||||
id 2 mod cells localg_table + @ to o
|
|
||||||
cx cy o CramCell :: .create id swap put identifier ;m
|
|
||||||
m: .print { o -- } ." IOLocalG(" o .getXY swap . . ." , g" o identifier 8 /mod . . ." ) " ;m
|
|
||||||
m: .inside { x y o -- wire } x y >iopermy o .isBottom? if 15 swap - then o CramCell :: .inside ;m
|
|
||||||
m: .getPath { o -- n } 0 0 ['] getBits o .listBits drop ;m
|
|
||||||
m: .setPath { n o -- } n ['] setBits o .listBits drop ;m
|
|
||||||
m: .optionCount { o -- n } 15 ;m
|
|
||||||
m: .getBit { o -- n } o identifier 8 mod ;m
|
|
||||||
m: .getRow { o -- n } o identifier 2/ ;m
|
|
||||||
m: .getOption { o -- n } o .enableBit .getBit if
|
|
||||||
o .getPath 1-
|
|
||||||
else
|
|
||||||
0
|
|
||||||
then ;m
|
|
||||||
m: .setOption { n o -- } n if
|
|
||||||
-1 o .enableBit .setBit
|
|
||||||
n 1+ o .setPath
|
|
||||||
else
|
|
||||||
0 o .enableBit .setBit
|
|
||||||
0 o .setPath ( for good measure )
|
|
||||||
then ;m
|
|
||||||
: iosp4v { offset o -- wire } o .getBit offset + o span4_vert ;
|
|
||||||
: iosp12v { offset o -- wire } o .getBit offset + o span12_vert ;
|
|
||||||
: iosp4h { offset o -- wire } o .getBit offset + o span4_horz ;
|
|
||||||
m: .optionWire { i o -- wire }
|
|
||||||
i 0 >= assert i o .optionCount < assert
|
|
||||||
i 0= if NotConnected .create exit then
|
|
||||||
1 +to i ( There's no 1 )
|
|
||||||
i case
|
|
||||||
5 of 0 o iosp4h exit endof
|
|
||||||
6 of 8 o iosp4h exit endof
|
|
||||||
7 of 0 o iosp12v exit endof
|
|
||||||
8 of 8 o iosp12v exit endof
|
|
||||||
9 of 16 o iosp12v exit endof
|
|
||||||
10 of 0 o iosp4v exit endof
|
|
||||||
11 of 8 o iosp4v exit endof
|
|
||||||
12 of 16 o iosp4v exit endof
|
|
||||||
13 of 24 o iosp4v exit endof
|
|
||||||
14 of 32 o iosp4v exit endof
|
|
||||||
15 of 40 o iosp4v exit endof
|
|
||||||
endcase
|
|
||||||
i 3 - 1 o .getXY nip if negate then { x y }
|
|
||||||
o .getXY y + to y x + to x
|
|
||||||
( Could use .isLogic ? )
|
|
||||||
x 1 < if NotConnected .create exit then
|
|
||||||
x cells-width 1- >= if NotConnected .create exit then
|
|
||||||
y cells-height 1- >= if NotConnected .create exit then
|
|
||||||
y 1 < if NotConnected .create exit then
|
|
||||||
x y o .getBit Output .create
|
|
||||||
;m
|
|
||||||
|
|
||||||
IOLocalG0 implementation IOLocalG extension
|
|
||||||
m: .enableBit { o -- wire } 19 o .getRow 2* 1+ o .inside ;m
|
|
||||||
m: .listBits { x o -- } 16 o .getRow 2* 1+ o .inside x execute
|
|
||||||
16 o .getRow 2* o .inside x execute
|
|
||||||
17 o .getRow 2* 1+ o .inside x execute
|
|
||||||
18 o .getRow 2* 1+ o .inside x execute ;m
|
|
||||||
|
|
||||||
IOLocalG1 implementation IOLocalG extension
|
|
||||||
m: .enableBit { o -- wire } 19 o .getRow 2* o .inside ;m
|
|
||||||
m: .listBits { x o -- } 20 o .getRow 2* 1+ o .inside x execute
|
|
||||||
20 o .getRow 2* o .inside x execute
|
|
||||||
17 o .getRow 2* o .inside x execute
|
|
||||||
18 o .getRow 2* o .inside x execute ;m
|
|
||||||
|
|
||||||
: optcount { n bit wire -- n } n 1+ ;
|
|
||||||
: optget { goal n bit wire -- goal n } bit .getBit if n else goal then n 1+ ;
|
|
||||||
: optset { goal n bit wire -- goal n } goal n = bit .setBit goal n 1+ ;
|
|
||||||
: optwire { answer goal n bit wire -- answer goal n } n goal = if wire else answer then goal n 1+ ;
|
|
||||||
: cross { idx n -- off ii } idx n /mod swap over 1 and xor ;
|
|
||||||
|
|
||||||
SpanWire implementation CramCell extension
|
|
||||||
m: .optionCount { o -- n } 1 ['] optcount o .walk ;m
|
|
||||||
m: .getOption { o -- n } 0 1 ['] optget o .walk drop ;m
|
|
||||||
m: .setOption { n o -- } n 1 ['] optset o .walk 2drop ;m
|
|
||||||
m: .optionWire { i o -- wire } NotConnected .create i 1 ['] optwire o .walk 2drop ;m
|
|
||||||
|
|
||||||
Sp4HR implementation SpanWire extension
|
|
||||||
0 11 field index
|
|
||||||
m: .create { cx cy idx o -- o } cx idx 12 cross { ii } - cy o SpanWire :: .create
|
|
||||||
ii swap put index ;m
|
|
||||||
m: .print { o -- } ." Sp4HR(" o .getXY swap . . ." , " o index . ." ) " ;m
|
|
||||||
m: .walk { xt o -- } 6 -5 do xt o o .getXY swap i + swap CramCell .create .routes loop ;m
|
|
||||||
|
|
||||||
Sp4VB implementation SpanWire extension
|
|
||||||
0 11 field index
|
|
||||||
m: .create { cx cy idx o -- o } cx cy idx 12 cross { ii } + o SpanWire :: .create
|
|
||||||
ii swap put index ;m
|
|
||||||
m: .print { o -- } ." Sp4VB(" o .getXY swap . . ." , " o index . ." ) " ;m
|
|
||||||
m: .walk { xt o -- } 6 -5 do xt o o .getXY i + CramCell .create .routes loop ;m
|
|
||||||
|
|
||||||
Sp12HR implementation SpanWire extension
|
|
||||||
0 1 field index
|
|
||||||
m: .create { cx cy idx o -- o } cx idx 2 cross { ii } - cy o SpanWire :: .create
|
|
||||||
ii swap put index ;m
|
|
||||||
m: .print { o -- } ." Sp12HR(" o .getXY swap . . ." , " o index . ." ) " ;m
|
|
||||||
m: .walk { xt o -- } 13 -13 do xt o o .getXY swap i + swap CramCell .create .routes loop ;m
|
|
||||||
|
|
||||||
Sp12VB implementation SpanWire extension
|
|
||||||
0 1 field index
|
|
||||||
m: .create { cx cy idx o -- o } cx cy idx 2 cross { ii } + o SpanWire :: .create
|
|
||||||
ii swap put index ;m
|
|
||||||
m: .print { o -- } ." Sp12VB(" o .getXY swap . . ." , " o index . ." ) " ;m
|
|
||||||
m: .walk { xt o -- } 13 -13 do xt o o .getXY i + CramCell .create .routes loop ;m
|
|
||||||
|
|
||||||
IOPin implementation CramCell extension
|
|
||||||
0 1 field pinIndex
|
|
||||||
m: .create { x y pin o -- o } x y o CramCell :: .create pin swap put pinIndex ;m
|
|
||||||
m: .print { o -- } ." IOPin(" o .getXY swap . . o pinIndex . ." ) " ;m
|
|
||||||
m: .inside { x y o -- wire } o .getXY nip 0= if 15 y - to y then x y o CramCell :: .inside ;m
|
|
||||||
: nopullup { o -- }
|
|
||||||
o pinIndex 0= if
|
|
||||||
-1 37 7 o .inside .setBit
|
|
||||||
else
|
|
||||||
-1 37 12 o .inside .setBit
|
|
||||||
then
|
|
||||||
;
|
|
||||||
m: .makeInput { o -- }
|
|
||||||
1 o .setPinType
|
|
||||||
-1 o .enableBit .setBit
|
|
||||||
-1 o .inputEnableBit .setBit
|
|
||||||
o nopullup
|
|
||||||
(
|
|
||||||
o .getXY o pinIndex 0 IOInput .create
|
|
||||||
)
|
|
||||||
o .getXY o pinIndex 2* Output .create
|
|
||||||
;m
|
|
||||||
m: .makeOutput { o -- output }
|
|
||||||
25 o .setPinType
|
|
||||||
-1 o .enableBit .setBit
|
|
||||||
0 o .inputEnableBit .setBit
|
|
||||||
o nopullup
|
|
||||||
o .getXY o pinIndex IOOutput0 .create
|
|
||||||
;m
|
|
||||||
m: .getPinType { o -- n } 0 0 ['] getBits o .listBits drop ;m
|
|
||||||
m: .setPinType { n o -- } n ['] setBits o .listBits drop ;m
|
|
||||||
m: .listBits { x o -- ... }
|
|
||||||
5 2 o pinIndex 11 * + o .inside x execute
|
|
||||||
4 2 o pinIndex 11 * + o .inside x execute
|
|
||||||
5 0 o pinIndex 11 * + o .inside x execute
|
|
||||||
4 0 o pinIndex 11 * + o .inside x execute
|
|
||||||
4 4 o pinIndex 11 * + o .inside x execute
|
|
||||||
5 4 o pinIndex 11 * + o .inside x execute
|
|
||||||
;m
|
|
||||||
m: .enableBit { o -- bit } o pinIndex if 27 1 else 26 7 then o .inside ;m
|
|
||||||
m: .inputEnableBit { o -- bit } 27 9 o pinIndex 1 xor 2* - o .inside ;m
|
|
||||||
|
|
||||||
: ioOptWire { i o parity -- wire }
|
|
||||||
o .getXY i 2* parity xor i 4 >= if 1 xor then IOLocalG .create
|
|
||||||
;
|
|
||||||
|
|
||||||
IOInput implementation SpanWire extension
|
|
||||||
0 1 field pinIndex
|
|
||||||
0 1 field dinNum
|
|
||||||
m: .create { x y pin din o -- o } x y o CramCell :: .create pin swap put pinIndex din swap put dinNum ;m
|
|
||||||
m: .print { o -- } ." IOInput(" o .getXY swap . . o pinIndex . o dinNum . ." ) " ;m
|
|
||||||
m: .optionCount { o -- n } 0 ;m
|
|
||||||
m: .getOption { o -- n } 0 ;m
|
|
||||||
|
|
||||||
IOOutput implementation CramCell extension
|
|
||||||
0 1 field pinIndex
|
|
||||||
m: .create { x y pin o -- o } x y o CramCell :: .create pin swap put pinIndex ;m
|
|
||||||
m: .print { o -- } ." IOOutput(" o .getXY swap . . o pinIndex . ." ) " ;m
|
|
||||||
m: .inside { x y o -- wire } x y o .isBottom? if 15 swap - then o CramCell :: .inside ;m
|
|
||||||
m: .getPath { o -- n } 0 0 ['] getBits o .listBits drop ;m
|
|
||||||
m: .setPath { n o -- } n ['] setBits o .listBits drop ;m
|
|
||||||
m: .optionCount { o -- n } 9 ;m
|
|
||||||
m: .getOption { o -- n } o .enableBit .getBit if
|
|
||||||
o .getPath 1+
|
|
||||||
else
|
|
||||||
0
|
|
||||||
then ;m
|
|
||||||
m: .setOption { n o -- } n if
|
|
||||||
-1 o .enableBit .setBit
|
|
||||||
n 1- o .setPath
|
|
||||||
else
|
|
||||||
0 o .enableBit .setBit
|
|
||||||
0 o .setPath ( for good measure )
|
|
||||||
then ;m
|
|
||||||
m: .optionWire { i o -- wire }
|
|
||||||
i 0= if NotConnected .create exit then
|
|
||||||
i 1- o o pinIndex o .getParity xor ioOptWire ;m
|
|
||||||
|
|
||||||
IOOutput0 implementation IOOutput extension
|
|
||||||
m: .print { o -- } ." IOOutput0(" o .getXY swap . . o pinIndex . ." ) " ;m
|
|
||||||
m: .enableBit { o -- wire } 35 5 o pinIndex 5 * + o .inside ;m
|
|
||||||
m: .listBits { x o -- ... }
|
|
||||||
34 5 o pinIndex 5 * + o .inside x execute
|
|
||||||
35 4 o pinIndex 7 * + o .inside x execute
|
|
||||||
34 4 o pinIndex 7 * + o .inside x execute
|
|
||||||
;m
|
|
||||||
m: .getParity { o -- n } 0 ;m
|
|
||||||
|
|
||||||
IOOutput1 implementation IOOutput extension
|
|
||||||
m: .print { o -- } ." IOOutput1(" o .getXY swap . . o pinIndex . ." ) " ;m
|
|
||||||
m: .enableBit { o -- wire } 33 9 o .inside ;m
|
|
||||||
m: .listBits { x o -- ... }
|
|
||||||
32 9 o pinIndex 5 * + o .inside x execute
|
|
||||||
32 8 o pinIndex 7 * + o .inside x execute
|
|
||||||
33 8 o pinIndex 7 * + o .inside x execute
|
|
||||||
;m
|
|
||||||
m: .getParity { o -- n } 1 ;m
|
|
||||||
|
|
||||||
IOEnable implementation IOOutput extension
|
|
||||||
m: .print { o -- } ." IOEnable(" o .getXY swap . . o pinIndex . ." ) " ;m
|
|
||||||
m: .enableBit { o -- wire } 33 5 o .inside ;m
|
|
||||||
m: .listBits { x o -- ... }
|
|
||||||
32 5 o pinIndex 5 * + o .inside x execute
|
|
||||||
32 4 o pinIndex 7 * + o .inside x execute
|
|
||||||
33 4 o pinIndex 7 * + o .inside x execute
|
|
||||||
;m
|
|
||||||
m: .getParity { o -- n } 1 ;m
|
|
||||||
|
|
||||||
IOFabOutput implementation IOOutput extension
|
|
||||||
m: .create { x y o -- o } x y 0 o IOOutput :: .create ;m
|
|
||||||
m: .print { o -- } ." IOFabOutput(" o .getXY swap . . ." ) " ;m
|
|
||||||
m: .enableBit { o -- wire } 37 4 o .inside ;m
|
|
||||||
m: .listBits { x o -- ... }
|
|
||||||
37 5 o .inside x execute
|
|
||||||
36 4 o .inside x execute
|
|
||||||
36 5 o .inside x execute
|
|
||||||
;m
|
|
||||||
m: .getParity { o -- n } 0 ;m
|
|
||||||
|
|
||||||
LUTFFGlobal implementation CramCell extension
|
|
||||||
m: .print { o -- } ." LUTFFGlobal(" o .getXY swap . . ." ) " ;m
|
|
||||||
m: .getPath { o -- n } 0 0 ['] getBits o .listBits drop ;m
|
|
||||||
m: .setPath { n o -- } n ['] setBits o .listBits drop ;m
|
|
||||||
m: .optionCount { o -- n } 9 ;m
|
|
||||||
m: .getOption { o -- n } o .enableBit .getBit if
|
|
||||||
o .getPath 1+
|
|
||||||
else
|
|
||||||
0
|
|
||||||
then ;m
|
|
||||||
m: .setOption { n o -- } n if
|
|
||||||
-1 o .enableBit .setBit
|
|
||||||
n 1- o .setPath
|
|
||||||
else
|
|
||||||
0 o .enableBit .setBit
|
|
||||||
0 o .setPath ( for good measure )
|
|
||||||
then ;m
|
|
||||||
m: .optionWire { i o -- wire }
|
|
||||||
o .getXY i case
|
|
||||||
( TODO: glb_netwk )
|
|
||||||
5 of 0 o .getRow + LocalG .create exit endof
|
|
||||||
6 of 9 o .getRow + LocalG .create exit endof
|
|
||||||
7 of 16 o .getRow + LocalG .create exit endof
|
|
||||||
8 of 25 o .getRow + LocalG .create exit endof
|
|
||||||
endcase 2drop NotConnected .create ;m
|
|
||||||
|
|
||||||
FFSetReset implementation LUTFFGlobal extension
|
|
||||||
m: .print { o -- } ." FFSetReset(" o .getXY swap . . ." ) " ;m
|
|
||||||
m: .enableBit { o -- wire } 1 14 o .inside ;m
|
|
||||||
m: .listBits { x o -- ... }
|
|
||||||
0 15 o .inside x execute
|
|
||||||
0 14 o .inside x execute
|
|
||||||
1 15 o .inside x execute
|
|
||||||
;m
|
|
||||||
m: .getRow ( -- n ) 4 ;m
|
|
||||||
m: .optionWire { i o -- wire }
|
|
||||||
i 0 > i 5 < and if i 1- 2* GlobalNetwork .create exit then
|
|
||||||
i o LUTFFGlobal :: .optionWire ;m
|
|
||||||
|
|
||||||
FFEnable implementation LUTFFGlobal extension
|
|
||||||
m: .print { o -- } ." FFEnable(" o .getXY swap . . ." ) " ;m
|
|
||||||
m: .enableBit { o -- wire } 1 4 o .inside ;m
|
|
||||||
m: .listBits { x o -- ... }
|
|
||||||
0 5 o .inside x execute
|
|
||||||
0 4 o .inside x execute
|
|
||||||
1 5 o .inside x execute
|
|
||||||
;m
|
|
||||||
m: .getRow ( -- n ) 2 ;m
|
|
||||||
m: .optionWire { i o -- wire }
|
|
||||||
i 0 > i 5 < and if i 1- 2* 1+ GlobalNetwork .create exit then
|
|
||||||
i o LUTFFGlobal :: .optionWire ;m
|
|
||||||
|
|
||||||
FFClock implementation LUTFFGlobal extension
|
|
||||||
m: .print { o -- } ." FFClock(" o .getXY swap . . ." ) " ;m
|
|
||||||
m: .enableBit { o -- wire } 2 2 o .inside ;m
|
|
||||||
m: .optionCount { o -- n } 13 ;m
|
|
||||||
m: .listBits { x o -- ... }
|
|
||||||
0 3 o .inside x execute
|
|
||||||
1 2 o .inside x execute
|
|
||||||
0 2 o .inside x execute
|
|
||||||
2 1 o .inside x execute
|
|
||||||
;m
|
|
||||||
m: .optionWire { i o -- wire }
|
|
||||||
i 0 > i 9 < and if i 1- GlobalNetwork .create exit then
|
|
||||||
i 4 - o LUTFFGlobal :: .optionWire ;m
|
|
||||||
|
|
||||||
GlobalNetwork implementation
|
|
||||||
0 7 field index
|
|
||||||
m: .create { i o -- o } i o put index ;m
|
|
||||||
m: .print { o -- } ." GlobalNetwork(" o index . ." ) " ;m
|
|
||||||
m: .getOption { o -- n } 0 ;m
|
|
||||||
m: .optionCount { o -- n } 0 ;m
|
|
||||||
|
|
||||||
NotConnected implementation
|
|
||||||
m: .create ( o -- o ) ;m
|
|
||||||
m: .print { o -- } ." NotConnected" ;m
|
|
||||||
m: .getOption { o -- n } 0 ;m
|
|
||||||
m: .optionCount { o -- n } 0 ;m
|
|
||||||
|
|
||||||
: pin ( n -- o ) pin#s IOPin .create ;
|
|
||||||
|
|
||||||
: route { src dst -- f }
|
|
||||||
\ ." SRC: " src .print ." DST: " dst .print cr
|
|
||||||
src dst = if -1 exit then
|
|
||||||
dst .getOption { p }
|
|
||||||
p if src p dst .optionWire recurse exit then
|
|
||||||
dst .optionCount { n }
|
|
||||||
n 0 ?do
|
|
||||||
i dst .setOption
|
|
||||||
src i dst .optionWire recurse if -1 unloop exit then
|
|
||||||
0 dst .setOption
|
|
||||||
loop 0
|
|
||||||
;
|
|
||||||
|
|
||||||
: route. { src dst }
|
|
||||||
." ROUTE: "
|
|
||||||
begin src dst <> while
|
|
||||||
dst .print ." <- "
|
|
||||||
dst .getOption dst .optionWire to dst
|
|
||||||
repeat
|
|
||||||
src .print cr
|
|
||||||
;
|
|
||||||
|
|
||||||
previous
|
|
||||||
forth definitions
|
|
||||||
|
|
||||||
@ -1,203 +0,0 @@
|
|||||||
\ Copyright 2025 Bradley D. Nelson
|
|
||||||
\
|
|
||||||
\ Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
\ you may not use this file except in compliance with the License.
|
|
||||||
\ You may obtain a copy of the License at
|
|
||||||
\
|
|
||||||
\ http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
\
|
|
||||||
\ Unless required by applicable law or agreed to in writing, software
|
|
||||||
\ distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
\ See the License for the specific language governing permissions and
|
|
||||||
\ limitations under the License.
|
|
||||||
|
|
||||||
needs ice40_config.fs
|
|
||||||
|
|
||||||
ice40 definitions
|
|
||||||
vocabulary storage storage definitions
|
|
||||||
|
|
||||||
: ew! ( n a -- ) over 8 rshift over c! 1+ c! ;
|
|
||||||
: w, ( n -- ) here ew! 2 allot ;
|
|
||||||
|
|
||||||
create header1
|
|
||||||
$ff c, $00 c, $00 c, $ff c, ( Init blop, maybe not needed? )
|
|
||||||
$7e c, $aa c, $99 c, $7e c, ( Preamble )
|
|
||||||
$51 c, $00 c, ( Frequency 0=low, 1=medium, 2=high )
|
|
||||||
$01 c, $05 c, ( Reset CRC crc = 0xffff )
|
|
||||||
here header1 - constant header1#
|
|
||||||
|
|
||||||
create header2
|
|
||||||
$92 c, $0020 w, ( Set flags bit0=nosleep bit5=warmboot )
|
|
||||||
$62 c, cram-bank-width 1- w, ( Set bank width )
|
|
||||||
$82 c, $0000 w, ( Set bank offset to 0 )
|
|
||||||
here header2 - constant header2#
|
|
||||||
|
|
||||||
0 value bank-id
|
|
||||||
0 value bank-height
|
|
||||||
create bank-header
|
|
||||||
$72 c, here to bank-height 0 w, ( Set bank height, 5k only, upper vs lower )
|
|
||||||
$11 c, here to bank-id 0 c, ( Set bank )
|
|
||||||
$01 c, $01 c, ( Prefix )
|
|
||||||
here bank-header - constant bank-header#
|
|
||||||
|
|
||||||
create bank-footer
|
|
||||||
$00 c, $00 c, ( Suffix )
|
|
||||||
here bank-footer - constant bank-footer#
|
|
||||||
|
|
||||||
create header3
|
|
||||||
$72 c, bram-chunk-size w, ( Setting bank height? )
|
|
||||||
here header3 - constant header3#
|
|
||||||
|
|
||||||
0 value bram-bank
|
|
||||||
create bram-header1
|
|
||||||
$11 c, here to bram-bank 0 c, ( Setting bank )
|
|
||||||
here bram-header1 - constant bram-header1#
|
|
||||||
|
|
||||||
0 value bram-offset
|
|
||||||
0 value bram-bank-width
|
|
||||||
create bram-header2
|
|
||||||
$82 c, here to bram-offset 0 w, ( Setting bank offset )
|
|
||||||
$62 c, here to bram-bank-width 0 w, ( Setting bank width )
|
|
||||||
here bram-header2 - constant bram-header2#
|
|
||||||
|
|
||||||
0 value footer-crc
|
|
||||||
create footer
|
|
||||||
$22 c, here to footer-crc $0000 w, ( CRC )
|
|
||||||
$01 c, $06 c, ( Wakeup )
|
|
||||||
$00 c, ( Padding )
|
|
||||||
here footer - constant footer#
|
|
||||||
|
|
||||||
variable crc16
|
|
||||||
: +crc16 ( ch -- )
|
|
||||||
7 for
|
|
||||||
dup i rshift 1 and ( peel off one bit )
|
|
||||||
crc16 uw@ 15 rshift xor if $1021 else 0 then
|
|
||||||
crc16 uw@ 2* xor crc16 w!
|
|
||||||
next
|
|
||||||
drop
|
|
||||||
;
|
|
||||||
: *crc16 ( a n -- ) for aft dup c@ +crc16 1+ then next drop ;
|
|
||||||
: crc-write ( a n output -- ) >r 2dup *crc16 r> execute ;
|
|
||||||
|
|
||||||
: cram-write { output -- }
|
|
||||||
( write header )
|
|
||||||
header1 header1# output execute
|
|
||||||
$ffff crc16 w!
|
|
||||||
header2 header2# output crc-write
|
|
||||||
|
|
||||||
( Bank 0 )
|
|
||||||
0 bank-id c!
|
|
||||||
cram-height-lower bank-height ew!
|
|
||||||
bank-header bank-header# output crc-write
|
|
||||||
cram cram-bank-width cram-height-lower * 8 / output crc-write
|
|
||||||
bank-footer bank-footer# output crc-write
|
|
||||||
|
|
||||||
( Bank 1 )
|
|
||||||
1 bank-id c!
|
|
||||||
cram-height-upper bank-height ew!
|
|
||||||
bank-header bank-header# output crc-write
|
|
||||||
cram cram-bank-width cram-height-lower * 8 / +
|
|
||||||
cram-bank-width cram-height-upper * 8 / output crc-write
|
|
||||||
bank-footer bank-footer# output crc-write
|
|
||||||
|
|
||||||
( Bank 2 )
|
|
||||||
2 bank-id c!
|
|
||||||
cram-height-lower bank-height ew!
|
|
||||||
bank-header bank-header# output crc-write
|
|
||||||
cram cram-bank-width cram-height-lower cram-height-upper + * 8 / +
|
|
||||||
cram-bank-width cram-height-lower * 8 / output crc-write
|
|
||||||
bank-footer bank-footer# output crc-write
|
|
||||||
|
|
||||||
( Bank 3 )
|
|
||||||
3 bank-id c!
|
|
||||||
cram-height-upper bank-height ew!
|
|
||||||
bank-header bank-header# output crc-write
|
|
||||||
cram cram-bank-width cram-height-lower 2* cram-height-upper + * 8 / +
|
|
||||||
cram-bank-width cram-height-upper * 8 / output crc-write
|
|
||||||
bank-footer bank-footer# output crc-write
|
|
||||||
|
|
||||||
( BRAM Header )
|
|
||||||
header3 header3# output crc-write
|
|
||||||
|
|
||||||
( BRAM Bank 0 )
|
|
||||||
0 bram-bank c!
|
|
||||||
bram-header1 bram-header1# output crc-write
|
|
||||||
|
|
||||||
bram-chunk-size 0 * bram-offset ew!
|
|
||||||
bram-width-lower 1- bram-bank-width ew!
|
|
||||||
bram-header2 bram-header2# output crc-write
|
|
||||||
|
|
||||||
bram-chunk-size 1 * bram-offset ew!
|
|
||||||
bram-width-lower 1- bram-bank-width ew!
|
|
||||||
bram-header2 bram-header2# output crc-write
|
|
||||||
|
|
||||||
( BRAM Bank 1 )
|
|
||||||
1 bram-bank c!
|
|
||||||
bram-header1 bram-header1# output crc-write
|
|
||||||
|
|
||||||
bram-chunk-size 0 * bram-offset ew!
|
|
||||||
bram-width-upper 1- bram-bank-width ew!
|
|
||||||
bram-header2 bram-header2# output crc-write
|
|
||||||
|
|
||||||
bram-chunk-size 1 * bram-offset ew!
|
|
||||||
bram-width-upper 1- bram-bank-width ew!
|
|
||||||
bram-header2 bram-header2# output crc-write
|
|
||||||
|
|
||||||
( BRAM Bank 2 )
|
|
||||||
2 bram-bank c!
|
|
||||||
bram-header1 bram-header1# output crc-write
|
|
||||||
|
|
||||||
bram-chunk-size 0 * bram-offset ew!
|
|
||||||
bram-width-lower 1- bram-bank-width ew!
|
|
||||||
bram-header2 bram-header2# output crc-write
|
|
||||||
|
|
||||||
bram-chunk-size 1 * bram-offset ew!
|
|
||||||
bram-width-lower 1- bram-bank-width ew!
|
|
||||||
bram-header2 bram-header2# output crc-write
|
|
||||||
|
|
||||||
( BRAM Bank 3 )
|
|
||||||
3 bram-bank c!
|
|
||||||
bram-header1 bram-header1# output crc-write
|
|
||||||
|
|
||||||
bram-chunk-size 0 * bram-offset ew!
|
|
||||||
bram-width-upper 1- bram-bank-width ew!
|
|
||||||
bram-header2 bram-header2# output crc-write
|
|
||||||
|
|
||||||
bram-chunk-size 1 * bram-offset ew!
|
|
||||||
bram-width-upper 1- bram-bank-width ew!
|
|
||||||
bram-header2 bram-header2# output crc-write
|
|
||||||
|
|
||||||
( write footer )
|
|
||||||
$22 +crc16 ( Add first byte of footer )
|
|
||||||
crc16 uw@ footer-crc ew! ( Update CRC )
|
|
||||||
footer footer# output crc-write
|
|
||||||
;
|
|
||||||
|
|
||||||
0 value save-fh
|
|
||||||
: save-write ( a n -- ) save-fh write-file throw ;
|
|
||||||
|
|
||||||
ice40 definitions also storage
|
|
||||||
|
|
||||||
: save ( a n -- )
|
|
||||||
w/o bin create-file throw to save-fh
|
|
||||||
['] save-write cram-write
|
|
||||||
save-fh close-file throw
|
|
||||||
;
|
|
||||||
|
|
||||||
DEFINED? ice [IF]
|
|
||||||
also ice
|
|
||||||
DEFINED? ice_cram_open [IF]
|
|
||||||
|
|
||||||
: deploy
|
|
||||||
ice_cram_open
|
|
||||||
['] ice_cram_write cram-write
|
|
||||||
ice_cram_close
|
|
||||||
;
|
|
||||||
|
|
||||||
[THEN]
|
|
||||||
previous
|
|
||||||
[THEN]
|
|
||||||
|
|
||||||
previous
|
|
||||||
forth definitions
|
|
||||||
@ -1,104 +0,0 @@
|
|||||||
\ Copyright 2025 Bradley D. Nelson
|
|
||||||
\
|
|
||||||
\ Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
\ you may not use this file except in compliance with the License.
|
|
||||||
\ You may obtain a copy of the License at
|
|
||||||
\
|
|
||||||
\ http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
\
|
|
||||||
\ Unless required by applicable law or agreed to in writing, software
|
|
||||||
\ distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
\ See the License for the specific language governing permissions and
|
|
||||||
\ limitations under the License.
|
|
||||||
|
|
||||||
needs ice40_layout.fs
|
|
||||||
needs ice40_allocation.fs
|
|
||||||
|
|
||||||
ice40 synthesis definitions
|
|
||||||
|
|
||||||
39 constant LED_G
|
|
||||||
40 constant LED_B
|
|
||||||
41 constant LED_R
|
|
||||||
|
|
||||||
: XOR1 ( a b -- o ) NotConnected NotConnected $6666 LUT4 ;
|
|
||||||
: OR1 ( a b -- o ) NotConnected NotConnected $eeee LUT4 ;
|
|
||||||
: AND1 ( a b -- o ) NotConnected NotConnected $8888 LUT4 ;
|
|
||||||
: INVERT1 ( a b -- o ) NotConnected NotConnected NotConnected $5555 LUT4 ;
|
|
||||||
: BUFFER1 ( a b -- o ) NotConnected NotConnected NotConnected $aaaa LUT4 ;
|
|
||||||
|
|
||||||
: HA ( x y -- so co ) 2dup AND1 >r XOR1 r> ;
|
|
||||||
: FA ( x y z -- so co ) HA >r HA r> OR1 ;
|
|
||||||
|
|
||||||
: BUS ( v bus -- bus ) here >r , , r> ;
|
|
||||||
: UNBUS ( bus -- v bus ) dup cell+ @ swap @ ;
|
|
||||||
: nBUS ( v* n -- bus ) 0 swap 0 ?do BUS loop ;
|
|
||||||
: nUNBUS ( bus -- v* ) begin dup while UNBUS repeat drop ;
|
|
||||||
|
|
||||||
: NEARBY { wire -- wire } wire .getXY dup 2 < if 1+ else 1- then
|
|
||||||
2dup CramCell .create .isRam? if >r 1+ r> then
|
|
||||||
PLACE wire ;
|
|
||||||
|
|
||||||
: IN1PIN ( n -- bus ) pin .makeInput NEARBY BUFFER1 ;
|
|
||||||
: OUT1PIN! ( wire n -- ) pin .makeOutput NEARBY >r BUFFER1 r> route! ;
|
|
||||||
|
|
||||||
: INPINS ( p1..pn n -- wire ) 0 swap 0 ?do swap IN1PIN swap BUS loop ;
|
|
||||||
: OUTPINS! ( bus p1..pn n -- )
|
|
||||||
nBUS begin dup while
|
|
||||||
UNBUS >r swap UNBUS >r swap OUT1PIN! r> r>
|
|
||||||
repeat 2drop ;
|
|
||||||
|
|
||||||
: REVERSE ( a -- a' )
|
|
||||||
0 swap begin dup while
|
|
||||||
UNBUS >r swap BUS r>
|
|
||||||
repeat drop
|
|
||||||
;
|
|
||||||
|
|
||||||
: INVERT ( a -- a' )
|
|
||||||
dup 0= if exit then
|
|
||||||
UNBUS >r INVERT1 r> recurse BUS
|
|
||||||
;
|
|
||||||
|
|
||||||
: BUFFER ( a -- a' )
|
|
||||||
dup 0= if exit then
|
|
||||||
UNBUS >r BUFFER1 r> recurse BUS
|
|
||||||
;
|
|
||||||
|
|
||||||
: AND ( a b -- c )
|
|
||||||
dup 0= if nip exit then
|
|
||||||
UNBUS >r >r UNBUS r> swap >r AND1
|
|
||||||
r> r> recurse BUS
|
|
||||||
;
|
|
||||||
|
|
||||||
: OR ( a b -- c )
|
|
||||||
dup 0= if nip exit then
|
|
||||||
UNBUS >r >r UNBUS r> swap >r OR1
|
|
||||||
r> r> recurse BUS
|
|
||||||
;
|
|
||||||
|
|
||||||
: XOR ( a b -- c )
|
|
||||||
dup 0= if nip exit then
|
|
||||||
UNBUS >r >r UNBUS r> swap >r XOR1
|
|
||||||
r> r> recurse BUS
|
|
||||||
;
|
|
||||||
|
|
||||||
: +c ( a b ci -- c )
|
|
||||||
>r dup 0= if 2drop r> 0 BUS exit then r>
|
|
||||||
-rot
|
|
||||||
UNBUS >r >r UNBUS r> swap >r FA
|
|
||||||
r> r> rot recurse BUS
|
|
||||||
;
|
|
||||||
|
|
||||||
: + ( a b -- c ) NotConnected +c ;
|
|
||||||
|
|
||||||
: REGISTER ( n -- bus )
|
|
||||||
0 swap 0 ?do FFL swap BUS loop REVERSE ;
|
|
||||||
|
|
||||||
: REG! ( v a -- )
|
|
||||||
dup 0= if 2drop exit then
|
|
||||||
UNBUS >r >r UNBUS r> swap >r FF!
|
|
||||||
r> r> recurse
|
|
||||||
;
|
|
||||||
|
|
||||||
forth definitions
|
|
||||||
|
|
||||||
@ -29,9 +29,9 @@
|
|||||||
#include "common/calls.h"
|
#include "common/calls.h"
|
||||||
|
|
||||||
#ifndef UEFORTH_SIM
|
#ifndef UEFORTH_SIM
|
||||||
# define HEAP_SIZE (150 * 1024)
|
# define HEAP_SIZE (100 * 1024)
|
||||||
#else
|
#else
|
||||||
# define HEAP_SIZE (300 * 1024)
|
# define HEAP_SIZE (200 * 1024)
|
||||||
#endif
|
#endif
|
||||||
#define STACK_CELLS (4 * 1024)
|
#define STACK_CELLS (4 * 1024)
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,5 @@ needs ../common/phase2.fs
|
|||||||
needs ../common/tasks.fs
|
needs ../common/tasks.fs
|
||||||
needs ../common/streams.fs
|
needs ../common/streams.fs
|
||||||
needs platform.fs
|
needs platform.fs
|
||||||
needs ice40/ice40.fs
|
|
||||||
needs autoboot.fs
|
needs autoboot.fs
|
||||||
needs ../common/fini.fs
|
needs ../common/fini.fs
|
||||||
|
|||||||
24
site/BUILD
24
site/BUILD
@ -101,6 +101,30 @@ if PICO_ICE_ENABLED:
|
|||||||
])),
|
])),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if WINDOWS_ENABLED:
|
||||||
|
Alias('publish-win32', ' '.join([
|
||||||
|
Publish('publish-win32-rev',
|
||||||
|
'$dst/windows/uEf32.exe',
|
||||||
|
'uEf32-{{VERSION}}-{{REVSHORT}}.exe'),
|
||||||
|
Publish('publish-win32-ver',
|
||||||
|
'$dst/windows/uEf32.exe',
|
||||||
|
'uEf32-{{VERSION}}.exe'),
|
||||||
|
]))
|
||||||
|
PUBLISH_PARTS += [
|
||||||
|
Alias('publish-win64', ' '.join([
|
||||||
|
Publish('publish-win64-rev',
|
||||||
|
'$dst/windows/uEf64.exe',
|
||||||
|
'uEf64-{{VERSION}}-{{REVSHORT}}.exe'),
|
||||||
|
Publish('publish-win64-ver',
|
||||||
|
'$dst/windows/uEf64.exe',
|
||||||
|
'uEf64-{{VERSION}}.exe'),
|
||||||
|
])),
|
||||||
|
]
|
||||||
|
Alias('publish-win', ' '.join([
|
||||||
|
'publish-win32',
|
||||||
|
'publish-win64',
|
||||||
|
]))
|
||||||
|
|
||||||
Alias('publish', ' '.join([
|
Alias('publish', ' '.join([
|
||||||
Command('publish-index', ' '.join([
|
Command('publish-index', ' '.join([
|
||||||
'$src/tools/webindex.py',
|
'$src/tools/webindex.py',
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
runtime: go123
|
runtime: go121
|
||||||
|
|
||||||
default_expiration: "1m"
|
default_expiration: "1m"
|
||||||
|
|
||||||
|
|||||||
@ -25,27 +25,46 @@ limitations under the License.
|
|||||||
#include "menu.html"
|
#include "menu.html"
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
|
|
||||||
<h2>Building</h2>
|
<h2>Download</h2>
|
||||||
|
|
||||||
|
<h3>STABLE RELEASE</h3>
|
||||||
<p>
|
<p>
|
||||||
Unfortunately, Window Defender's heuristics falsely identify uEforth.exe builds as malware.
|
<a href="https://eforth.storage.googleapis.com/releases/uEf64-{{STABLE_VERSION}}.exe">uEf64-{{STABLE_VERSION}}.exe</a>
|
||||||
And recently Google Cloud also started identifying them as abuse.
|
- Window 64-bit EXE µEforth<br/>
|
||||||
As a result, I've removed hosting of them.
|
<i>Version: {{STABLE_VERSION}} (Stable)</i>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<h3>LONG TERM STABLE RELEASE</h3>
|
||||||
<p>
|
<p>
|
||||||
Instead build as follows (using the Windows Subsystem for Linux):
|
<a href="https://eforth.storage.googleapis.com/releases/uEf64-{{OLD_STABLE_VERSION}}.exe">uEf64-{{OLD_STABLE_VERSION}}.exe</a>
|
||||||
<pre>
|
- Window 64-bit EXE µEforth<br/>
|
||||||
sudo apt install ninja-build
|
<i>Version: {{OLD_STABLE_VERSION}} (Long-term Stable)</i>
|
||||||
git clone https://github.com/flagxor/ueforth
|
</p>
|
||||||
cd ueforth
|
|
||||||
./configure.py
|
<h3>Beta Release</h3>
|
||||||
ninja
|
<p>
|
||||||
</pre>
|
<a href="https://eforth.storage.googleapis.com/releases/uEf64-{{VERSION}}.exe">uEf64-{{VERSION}}.exe</a>
|
||||||
|
- Window 64-bit EXE µEforth<br/>
|
||||||
|
<i>Version: {{VERSION}} (Beta)</i>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<b>NOTE: 32-bit builds are no longer published. They can still be built from source.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a href="https://eforth.storage.googleapis.com/releases/archive.html" target="_blank">Release Archive</a>
|
||||||
|
- Prior Releases
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a href="https://github.com/flagxor/ueforth" target="_blank">http://github.com/flagxor/ueforth</a>
|
||||||
|
- Complete Unprocessed Source Code
|
||||||
|
</p>
|
||||||
|
|
||||||
<h2>µEforth</h2>
|
<h2>µEforth</h2>
|
||||||
|
|
||||||
<h3>µEforth Words</h3>
|
<h3>µEforth Words</h3>
|
||||||
|
|||||||
@ -65,7 +65,7 @@ int main(int argc, char *argv[]) {
|
|||||||
#undef Z
|
#undef Z
|
||||||
} else if (argc == 2 && strcmp(argv[1], "dict") == 0) {
|
} else if (argc == 2 && strcmp(argv[1], "dict") == 0) {
|
||||||
#define V(name) \
|
#define V(name) \
|
||||||
printf(" Create(\"" #name "-builtins\", %d);\n", BUILTIN_FORK); \
|
printf(" Create(\"" #name "-builtins\", %d);\n", BUILTIN_FORK, OP_DOCREATE); \
|
||||||
printf(" COMMA(%d);\n", VOC_ ## name);
|
printf(" COMMA(%d);\n", VOC_ ## name);
|
||||||
VOCABULARY_LIST
|
VOCABULARY_LIST
|
||||||
#undef V
|
#undef V
|
||||||
@ -84,7 +84,7 @@ int main(int argc, char *argv[]) {
|
|||||||
#define G_SYS 256
|
#define G_SYS 256
|
||||||
printf(" const g_sys = %d;\n", G_SYS);
|
printf(" const g_sys = %d;\n", G_SYS);
|
||||||
#define EMITSYS(name) \
|
#define EMITSYS(name) \
|
||||||
printf(" const g_sys_%s = %d;\n", #name, 256 + 4 * (int) (((cell_t *) &g_sys->name) - (cell_t*) g_sys));
|
printf(" const g_sys_%s = %d;\n", #name, 256 + 4 * (((cell_t *) &g_sys->name) - (cell_t*) g_sys));
|
||||||
EMITSYS(heap);
|
EMITSYS(heap);
|
||||||
EMITSYS(current);
|
EMITSYS(current);
|
||||||
EMITSYS(context);
|
EMITSYS(context);
|
||||||
|
|||||||
Reference in New Issue
Block a user