Browse Source

Removed old files

main
Devine Lu Linvega 4 months ago
parent
commit
16c597bb12
  1. 119
      etc/asma-test.sh
  2. 103
      etc/asma.lua
  3. 74
      etc/asma.moon
  4. 3
      etc/autotest/.gitignore
  5. 11
      etc/autotest/asoundrc
  6. 332
      etc/autotest/main.c
  7. 20
      etc/autotest/run.sh
  8. 85
      etc/cores/uxn-abc-disp.c
  9. 81
      etc/cores/uxn-abc.c
  10. 123
      etc/cores/uxn-tnl.c
  11. 16
      etc/utos/build.sh
  12. 39
      etc/utos/utos.c
  13. 103
      etc/uxambly-translate.moon

119
etc/asma-test.sh

@ -1,119 +0,0 @@
#!/bin/sh
set -e
cd "$(dirname "${0}")/.."
rm -rf asma-test
mkdir asma-test
expect_failure() {
cat > asma-test/in.tal
bin/uxncli asma-test/asma.rom asma-test/in.tal asma-test/out.rom 2> asma-test/asma.log
if ! grep -qF "${1}" asma-test/asma.log; then
echo "error: asma didn't report error ${1} in faulty code"
cat asma-test/asma.log
exit 1
fi
}
echo 'Assembling asma with uxnasm'
if ! bin/uxnasm projects/software/asma.tal asma-test/asma.rom > asma-test/uxnasm.log; then
echo 'Failed to assemble asma!'
cat asma-test/uxnasm.log
exit 1
fi
for F in $(find projects -path projects/library -prune -false -or -path projects/assets -prune -false -or -type f -name '*.tal' | sort); do
echo "Comparing assembly of ${F}"
UASM_BASE="asma-test/uxnasm-$(basename "${F%.tal}")"
if ! bin/uxnasm "${F}" "${UASM_BASE}.rom" 2> "${UASM_BASE}.log"; then
echo "error: uxnasm failed to assemble ${F}"
cat "${UASM_BASE}.log"
exit 1
fi
xxd "${UASM_BASE}.rom" > "${UASM_BASE}.hex"
ASMA_BASE="asma-test/asma-$(basename "${F%.tal}")"
bin/uxncli asma-test/asma.rom "${F}" "${ASMA_BASE}.rom" 2> "${ASMA_BASE}.log"
if ! grep -qF 'bytes of heap used' "${ASMA_BASE}.log"; then
echo "error: asma failed to assemble ${F}, while uxnasm succeeded"
cat "${ASMA_BASE}.log"
exit 1
fi
xxd "${ASMA_BASE}.rom" > "${ASMA_BASE}.hex"
diff -u "${UASM_BASE}.hex" "${ASMA_BASE}.hex"
done
expect_failure 'Invalid hexadecimal: $defg' <<'EOD'
|1000 $defg
EOD
expect_failure 'Invalid hexadecimal: #defg' <<'EOD'
|1000 #defg
EOD
expect_failure 'Invalid hexadecimal: #' <<'EOD'
|1000 #
EOD
expect_failure 'Invalid hexadecimal: #0' <<'EOD'
|1000 #0
EOD
expect_failure 'Invalid hexadecimal: #000' <<'EOD'
|1000 #000
EOD
expect_failure 'Label not found: 0' <<'EOD'
|1000 0
EOD
expect_failure 'Label not found: 000' <<'EOD'
|1000 000
EOD
expect_failure 'Address not in zero page: .hello' <<'EOD'
|1000 @hello
.hello
EOD
expect_failure 'Address not in zero page: -hello' <<'EOD'
|1000 @hello
-hello
EOD
expect_failure 'Address outside range: ,hello' <<'EOD'
|1000 @hello
|2000 ,hello
EOD
expect_failure 'Label not found: hello' <<'EOD'
hello
EOD
expect_failure 'Macro already exists: %me' <<'EOD'
%me { #00 }
%me { #01 }
EOD
expect_failure 'Memory overwrite: SUB' <<'EOD'
|2000 ADD
|1000 SUB
EOD
# expect_failure 'Recursion level too deep:' <<'EOD'
# %me { you }
# %you { me }
# |1000 me
# EOD
# expect_failure 'Recursion level too deep: ~asma-test/in.tal' <<'EOD'
# ~asma-test/in.tal
# EOD
expect_failure 'Label not found: ;blah' <<'EOD'
|1000 ;blah
EOD
expect_failure 'Label not found: :blah' <<'EOD'
|1000 :blah
EOD
expect_failure 'Label not found: =blah' <<'EOD'
|1000 =blah
EOD
expect_failure 'Label not found: -blah' <<'EOD'
|1000 -blah
EOD
expect_failure 'Label not found: ,blah' <<'EOD'
|1000 ,blah
EOD
expect_failure 'Label not found: .blah' <<'EOD'
|1000 .blah
EOD
expect_failure "Label not found: 'a" <<'EOD'
|1000 'a
EOD
echo 'All OK'

103
etc/asma.lua

@ -1,103 +0,0 @@
local output = assert(io.open('.asma.tal', 'w'))
local process_subtree
process_subtree = function(items)
local middle = math.floor(#items / 2 + 1.25)
local node = items[middle]
if not node then
return
end
node.left = process_subtree((function()
local _accum_0 = { }
local _len_0 = 1
for i, item in ipairs(items) do
if i < middle then
_accum_0[_len_0] = item
_len_0 = _len_0 + 1
end
end
return _accum_0
end)())
node.right = process_subtree((function()
local _accum_0 = { }
local _len_0 = 1
for i, item in ipairs(items) do
if i > middle then
_accum_0[_len_0] = item
_len_0 = _len_0 + 1
end
end
return _accum_0
end)())
return node
end
local process_tree
process_tree = function(items)
local sorted_items
do
local _accum_0 = { }
local _len_0 = 1
for _index_0 = 1, #items do
local item = items[_index_0]
_accum_0[_len_0] = item
_len_0 = _len_0 + 1
end
sorted_items = _accum_0
end
table.sort(sorted_items, function(a, b)
return a.order < b.order
end);
(process_subtree(sorted_items)).label = '&_entry'
for _index_0 = 1, #items do
local item = items[_index_0]
output:write(('\t%-11s %-10s %-12s %s%s\n'):format(item.label, item.left and item.left.ref or ' $2', (item.right and item.right.ref or ' $2') .. item.extra, item.key, item.rest))
end
end
local parse_tree
parse_tree = function(it)
local items = { }
for l in it do
if l == '' then
process_tree(items)
output:write('\n')
return
end
local item = {
extra = ''
}
item.key, item.rest = l:match('^%s*%S+%s+%S+%s+%S+%s+(%S+)(.*)')
if item.key:match('^%&') then
item.extra = (' %s'):format(item.key)
item.key, item.rest = item.rest:match('^%s+(%S+)(.*)')
end
if item.key:match('^%"') then
item.order = item.key:sub(2)
elseif item.key:match('^%x%x') then
item.order = string.char(tonumber(item.key, 16))
else
error(('unknown key: %q'):format(item.key))
end
if item.order:match('^%a') then
item.label = ('&%s'):format(item.order)
elseif item.order:match('^.$') then
item.label = ('&%x'):format(item.order:byte())
else
error(('unknown label: %q'):format(item.order))
end
item.ref = (':%s'):format(item.label)
table.insert(items, item)
end
end
local it = assert(io.lines('projects/library/asma.tal'))
local waiting_for_cut = true
for l in it do
output:write(l)
output:write('\n')
if l:find('--- cut here ---', 1, true) then
waiting_for_cut = false
end
if not waiting_for_cut and '@' == l:sub(1, 1) then
parse_tree(it)
end
end
output:close()
return os.execute('mv .asma.tal projects/library/asma.tal')

74
etc/asma.moon

@ -1,74 +0,0 @@
--
-- Asma tree helper script
--
-- This script balances the trees at the end of projects/library/asma.tal.
--
-- To run, you need Lua or LuaJIT, and just run etc/asma.lua from the top
-- directory of Uxn's git repository:
--
-- lua etc/asma.lua
--
-- This file is written in MoonScript, which is a language that compiles to
-- Lua, the same way as e.g. CoffeeScript compiles to JavaScript. Since
-- installing MoonScript has more dependencies than Lua, the compiled
-- etc/asma.lua is kept in Uxn's repository and will be kept updated as this
-- file changes.
--
output = assert io.open '.asma.tal', 'w'
process_subtree = (items) ->
middle = math.floor #items / 2 + 1.25
node = items[middle]
if not node
return
node.left = process_subtree [ item for i, item in ipairs items when i < middle ]
node.right = process_subtree [ item for i, item in ipairs items when i > middle ]
node
process_tree = (items) ->
sorted_items = [ item for item in *items ]
table.sort sorted_items, (a, b) -> a.order < b.order
(process_subtree sorted_items).label = '&_entry'
for item in *items
output\write '\t%-11s %-10s %-12s %s%s\n'\format item.label, item.left and item.left.ref or ' $2', (item.right and item.right.ref or ' $2') .. item.extra, item.key, item.rest
parse_tree = (it) ->
items = {}
for l in it
if l == ''
process_tree items
output\write '\n'
return
item = { extra: '' }
item.key, item.rest = l\match '^%s*%S+%s+%S+%s+%S+%s+(%S+)(.*)'
if item.key\match '^%&'
item.extra = ' %s'\format item.key
item.key, item.rest = item.rest\match '^%s+(%S+)(.*)'
if item.key\match '^%"'
item.order = item.key\sub 2
elseif item.key\match '^%x%x'
item.order = string.char tonumber item.key, 16
else
error 'unknown key: %q'\format item.key
if item.order\match '^%a'
item.label = '&%s'\format item.order
elseif item.order\match '^.$'
item.label = '&%x'\format item.order\byte!
else
error 'unknown label: %q'\format item.order
item.ref = ':%s'\format item.label
table.insert items, item
it = assert io.lines 'projects/library/asma.tal'
waiting_for_cut = true
for l in it
output\write l
output\write '\n'
if l\find '--- cut here ---', 1, true
waiting_for_cut = false
if not waiting_for_cut and '@' == l\sub 1, 1
parse_tree it
output\close!
os.execute 'mv .asma.tal projects/library/asma.tal'

3
etc/autotest/.gitignore vendored

@ -1,3 +0,0 @@
/autotest
/fix_fft.c
/test.ppm

11
etc/autotest/asoundrc

@ -1,11 +0,0 @@
pcm.!default {
type file
slave.pcm null
file /proc/self/fd/3
format "raw"
}
pcm.null {
type null
}

332
etc/autotest/main.c

@ -1,332 +0,0 @@
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <math.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define WIDTH 512
#define HEIGHT 320
#define str(x) stra(x)
#define stra(x) #x
#define die(fnname) \
do { \
perror(fnname); \
exit(EXIT_FAILURE); \
} while(0)
#define x(fn, ...) \
do { \
if(fn(__VA_ARGS__) < 0) { \
perror(#fn); \
exit(EXIT_FAILURE); \
} \
} while(0)
int fix_fft(short *fr, short *fi, short m, short inverse);
static pid_t
launch_xvfb(void)
{
char displayfd[16];
int r;
pid_t pid;
int fds[2];
x(pipe2, &fds[0], 0);
pid = fork();
if(pid < 0) {
die("fork");
} else if(!pid) {
x(snprintf, displayfd, sizeof(displayfd), "%d", fds[1]);
x(close, fds[0]);
execlp("Xvfb", "Xvfb", "-screen", "0", str(WIDTH) "x" str(HEIGHT) "x24", "-fbdir", ".", "-displayfd", displayfd, "-nolisten", "tcp", NULL);
die("execl");
exit(EXIT_FAILURE);
}
x(close, fds[1]);
r = read(fds[0], &displayfd[1], sizeof(displayfd) - 1);
if(r < 0) die("read");
x(close, fds[0]);
displayfd[r] = '\0';
displayfd[0] = ':';
x(setenv, "DISPLAY", displayfd, 1);
x(setenv, "ALSA_CONFIG_PATH", "asoundrc", 1);
return pid;
}
static pid_t
launch_uxnemu(int *write_fd, int *read_fd, int *sound_fd)
{
pid_t pid;
int fds[6];
x(pipe2, &fds[0], O_CLOEXEC);
x(pipe2, &fds[2], O_CLOEXEC);
x(pipe2, &fds[4], O_CLOEXEC);
pid = fork();
if(pid < 0) {
die("fork");
} else if(!pid) {
x(dup2, fds[0], 0);
x(dup2, fds[3], 1);
x(dup2, fds[5], 3);
execl("../../bin/uxnemu", "uxnemu", "autotest.rom", NULL);
die("execl");
}
x(close, fds[0]);
x(close, fds[3]);
x(close, fds[5]);
*write_fd = fds[1];
*read_fd = fds[2];
*sound_fd = fds[4];
return pid;
}
static void
terminate(pid_t pid)
{
int signals[] = {SIGINT, SIGTERM, SIGKILL};
int status;
size_t i;
for(i = 0; i < sizeof(signals) / sizeof(int) * 10; ++i) {
if(kill(pid, signals[i / 10])) {
break;
}
usleep(100000);
if(pid == waitpid(pid, &status, WNOHANG)) {
return;
}
}
waitpid(pid, &status, 0);
}
static int
open_framebuffer(void)
{
for(;;) {
int fd = open("Xvfb_screen0", O_RDONLY | O_CLOEXEC);
if(fd >= 0) {
return fd;
}
if(errno != ENOENT) {
perror("open");
return fd;
}
usleep(100000);
}
}
#define PPM_HEADER "P6\n" str(WIDTH) " " str(HEIGHT) "\n255\n"
static void
save_screenshot(int fb_fd, const char *filename)
{
unsigned char screen[WIDTH * HEIGHT * 4 + 4];
int fd = open(filename, O_WRONLY | O_CREAT, 0666);
int i;
if(fd < 0) {
die("screenshot open");
}
x(write, fd, PPM_HEADER, strlen(PPM_HEADER));
x(lseek, fb_fd, 0xca0, SEEK_SET);
x(read, fb_fd, &screen[4], WIDTH * HEIGHT * 4);
for(i = 0; i < WIDTH * HEIGHT; ++i) {
screen[i * 3 + 2] = screen[i * 4 + 4];
screen[i * 3 + 1] = screen[i * 4 + 5];
screen[i * 3 + 0] = screen[i * 4 + 6];
}
x(write, fd, screen, WIDTH * HEIGHT * 3);
x(close, fd);
}
static void
systemf(char *format, ...)
{
char *command;
va_list ap;
va_start(ap, format);
x(vasprintf, &command, format, ap);
system(command);
free(command);
}
int uxn_read_fd, sound_fd;
static int
byte(void)
{
char c;
if(read(uxn_read_fd, &c, 1) != 1) {
return 0;
}
return (unsigned char)c;
}
#define NEW_FFT_SIZE_POW2 10
#define NEW_FFT_SIZE (1 << NEW_FFT_SIZE_POW2)
#define NEW_FFT_USEC (5000 * NEW_FFT_SIZE / 441)
unsigned char left_peak, right_peak;
static int
detect_peak(short *real, short *imag)
{
int i, peak = 0, peak_i;
for(i = 0; i < NEW_FFT_SIZE; ++i) {
int v = real[i] * real[i] + imag[i] * imag[i];
if(peak < v) {
peak = v;
peak_i = i;
} else if(peak > v * 10) {
return peak_i;
}
}
return 0;
}
static int
analyse_sound(short *samples)
{
short real[NEW_FFT_SIZE], imag[NEW_FFT_SIZE];
int i;
for(i = 0; i < NEW_FFT_SIZE * 2; ++i) {
if(samples[i * 2]) break;
}
if(i == NEW_FFT_SIZE * 2) return 0;
for(i = 0; i < NEW_FFT_SIZE; ++i) {
real[i] = samples[i * 4];
imag[i] = samples[i * 4 + 2];
}
fix_fft(real, imag, NEW_FFT_SIZE_POW2, 0);
return detect_peak(real, imag);
}
static int
read_sound(void)
{
static short samples[NEW_FFT_SIZE * 4];
static size_t len = 0;
int r = read(sound_fd, ((char *)samples) + len, sizeof(samples) - len);
if(r > 0) {
len += r;
if(len == sizeof(samples)) {
left_peak = analyse_sound(&samples[0]);
right_peak = analyse_sound(&samples[1]);
len = 0;
return 1;
}
}
return 0;
}
static void
main_loop(int uxn_write_fd, int fb_fd)
{
struct timeval next_sound = {0, 0};
for(;;) {
struct timeval now;
struct timeval *timeout;
fd_set fds;
FD_ZERO(&fds);
FD_SET(uxn_read_fd, &fds);
x(gettimeofday, &now, NULL);
if(now.tv_sec > next_sound.tv_sec || (now.tv_sec == next_sound.tv_sec && now.tv_usec > next_sound.tv_usec)) {
FD_SET(sound_fd, &fds);
timeout = NULL;
} else {
now.tv_sec = 0;
now.tv_usec = NEW_FFT_USEC;
timeout = &now;
}
x(select, uxn_read_fd > sound_fd ? uxn_read_fd + 1 : sound_fd + 1, &fds, NULL, NULL, timeout);
if(FD_ISSET(uxn_read_fd, &fds)) {
int c, x, y;
unsigned char blue;
switch(c = byte()) {
case 0x00: /* also used for EOF */
printf("exiting\n");
return;
/* 01-06 mouse */
case 0x01 ... 0x05:
systemf("xdotool click %d", c);
break;
case 0x06:
x = (byte() << 8) | byte();
y = (byte() << 8) | byte();
systemf("xdotool mousemove %d %d", x, y);
break;
/* 07-08 Screen */
case 0x07:
x = (byte() << 8) | byte();
y = (byte() << 8) | byte();
lseek(fb_fd, 0xca0 + (x + y * WIDTH) * 4, SEEK_SET);
read(fb_fd, &blue, 1);
blue = blue / 0x11;
write(uxn_write_fd, &blue, 1);
break;
case 0x08:
save_screenshot(fb_fd, "test.ppm");
break;
/* 09-0a Audio */
case 0x09:
write(uxn_write_fd, &left_peak, 1);
break;
case 0x0a:
write(uxn_write_fd, &right_peak, 1);
break;
/* 11-7e Controller/key */
case 0x11 ... 0x1c:
systemf("xdotool key F%d", c - 0x10);
break;
case '0' ... '9':
case 'A' ... 'Z':
case 'a' ... 'z':
systemf("xdotool key %c", c);
break;
default:
printf("unhandled command 0x%02x\n", c);
break;
}
}
if(FD_ISSET(sound_fd, &fds)) {
if(!next_sound.tv_sec) {
x(gettimeofday, &next_sound, NULL);
}
next_sound.tv_usec += NEW_FFT_USEC * read_sound();
if(next_sound.tv_usec > 1000000) {
next_sound.tv_usec -= 1000000;
++next_sound.tv_sec;
}
}
}
}
int
main(void)
{
pid_t xvfb_pid = launch_xvfb();
int fb_fd = open_framebuffer();
if(fb_fd >= 0) {
int uxn_write_fd;
pid_t uxnemu_pid = launch_uxnemu(&uxn_write_fd, &uxn_read_fd, &sound_fd);
main_loop(uxn_write_fd, fb_fd);
terminate(uxnemu_pid);
x(close, uxn_write_fd);
x(close, uxn_read_fd);
x(close, sound_fd);
x(close, fb_fd);
}
terminate(xvfb_pid);
return 0;
}

20
etc/autotest/run.sh

@ -1,20 +0,0 @@
#!/bin/sh -e
cd "$(dirname "${0}")"
if ! which Xvfb 2>/dev/null; then
echo "error: ${0} depends on Xvfb"
exit 1
fi
if ! which xdotool 2>/dev/null; then
echo "error: ${0} depends on xdotool"
exit 1
fi
if [ ! -e fix_fft.c ]; then
wget https://gist.githubusercontent.com/Tomwi/3842231/raw/67149b6ec81cfb6ac1056fd23a3bb6ce1f0a5188/fix_fft.c
fi
if which clang-format 2>/dev/null; then
( cd ../.. && clang-format -i etc/autotest/main.c )
fi
../../bin/uxnasm autotest.tal autotest.rom
gcc -std=gnu89 -Wall -Wextra -o autotest main.c fix_fft.c -lm
./autotest

85
etc/cores/uxn-abc-disp.c

@ -1,85 +0,0 @@
#include "uxn.h"
/*
Copyright (u) 2022-2023 Devine Lu Linvega, Andrew Alderwick, Andrew Richards
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/
#define FLIP { s = ins & 0x40 ? &u->wst : &u->rst; }
#define JUMP(x) { if(m2) pc = (x); else pc += (Sint8)(x); }
#define POP1(o) { o = s->dat[--*sp]; }
#define POP2(o) { o = s->dat[--*sp] | (s->dat[--*sp] << 0x8); }
#define POPx(o) { if(m2) { POP2(o) } else POP1(o) }
#define PUSH1(y) { s->dat[s->ptr++] = (y); }
#define PUSH2(y) { tt = (y); s->dat[s->ptr++] = tt >> 0x8; s->dat[s->ptr++] = tt; }
#define PUSHx(y) { if(m2) { PUSH2(y) } else PUSH1(y) }
#define PEEK(o, x, r) { if(m2) { r = (x); o = ram[r++] << 8 | ram[r]; } else o = ram[(x)]; }
#define POKE(x, y, r) { if(m2) { r = (x); ram[r++] = y >> 8; ram[r] = y; } else ram[(x)] = (y); }
#define DEVR(o, p) { if(m2) { o = (emu_dei(u, p) << 8) | emu_dei(u, p + 1); } else o = emu_dei(u, p); }
#define DEVW(p, y) { if(m2) { emu_deo(u, p, y >> 8); emu_deo(u, p + 1, y); } else emu_deo(u, p, y); }
#define next { ins = ram[pc++]; \
m2 = ins & 0x20; \
s = ins & 0x40 ? &u->rst : &u->wst; \
if(ins & 0x80) kp = s->ptr, sp = &kp; else sp = &s->ptr; \
goto *lut[ins & 0x1f]; }
int
uxn_eval(Uxn *u, Uint16 pc)
{
Uint8 t, kp, *sp, ins, m2, *ram = u->ram;
Uint16 tt, a, b, c;
Stack *s;
static void* lut[] = {
&&_imm, &&_inc, &&_pop, &&_nip, &&_swp, &&_rot, &&_dup, &&_ovr,
&&_equ, &&_neq, &&_gth, &&_lth, &&_jmp, &&_jcn, &&_jsr, &&_sth,
&&_ldz, &&_stz, &&_ldr, &&_str, &&_lda, &&_sta, &&_dei, &&_deo,
&&_add, &&_sub, &&_mul, &&_div, &&_and, &&_ora, &&_eor, &&_sft };
if(!pc || u->dev[0x0f]) return 0;
next
_imm:
switch(ins) {
case 0x00: /* BRK */ return 1;
case 0x20: /* JCI */ POP1(b) if(!b) { pc += 2; break; }
case 0x40: /* JMI */ a = ram[pc++] << 8 | ram[pc++]; pc += a; break;
case 0x60: /* JSI */ PUSH2(pc + 2) a = ram[pc++] << 8 | ram[pc++]; pc += a; break;
case 0x80: case 0xc0: /* LIT */ PUSH1(ram[pc++]) break;
case 0xa0: case 0xe0: /* LIT2 */ PUSH1(ram[pc++]) PUSH1(ram[pc++]) break;
} next
_inc: POPx(a) PUSHx(a + 1) next
_pop: POPx(a) next
_nip: POPx(a) POPx(b) PUSHx(a) next
_swp: POPx(a) POPx(b) PUSHx(a) PUSHx(b) next
_rot: POPx(a) POPx(b) POPx(c) PUSHx(b) PUSHx(a) PUSHx(c) next
_dup: POPx(a) PUSHx(a) PUSHx(a) next
_ovr: POPx(a) POPx(b) PUSHx(b) PUSHx(a) PUSHx(b) next
_equ: POPx(a) POPx(b) PUSH1(b == a) next
_neq: POPx(a) POPx(b) PUSH1(b != a) next
_gth: POPx(a) POPx(b) PUSH1(b > a) next
_lth: POPx(a) POPx(b) PUSH1(b < a) next
_jmp: POPx(a) JUMP(a) next
_jcn: POPx(a) POP1(b) if(b) JUMP(a) next
_jsr: POPx(a) FLIP PUSH2(pc) JUMP(a) next
_sth: POPx(a) FLIP PUSHx(a) next
_ldz: POP1(a) PEEK(b, a, t) PUSHx(b) next
_stz: POP1(a) POPx(b) POKE(a, b, t) next
_ldr: POP1(a) PEEK(b, pc + (Sint8)a, tt) PUSHx(b) next
_str: POP1(a) POPx(b) POKE(pc + (Sint8)a, b, tt) next
_lda: POP2(a) PEEK(b, a, tt) PUSHx(b) next
_sta: POP2(a) POPx(b) POKE(a, b, tt) next
_dei: POP1(a) DEVR(b, a) PUSHx(b) next
_deo: POP1(a) POPx(b) DEVW(a, b) next
_add: POPx(a) POPx(b) PUSHx(b + a) next
_sub: POPx(a) POPx(b) PUSHx(b - a) next
_mul: POPx(a) POPx(b) PUSHx(b * a) next
_div: POPx(a) POPx(b) PUSHx(a ? b / a : 0) next
_and: POPx(a) POPx(b) PUSHx(b & a) next
_ora: POPx(a) POPx(b) PUSHx(b | a) next
_eor: POPx(a) POPx(b) PUSHx(b ^ a) next
_sft: POP1(a) POPx(b) PUSHx(b >> (a & 0xf) << (a >> 4)) next
}

81
etc/cores/uxn-abc.c

@ -1,81 +0,0 @@
#include "uxn.h"
/*
Copyright (u) 2022-2023 Devine Lu Linvega, Andrew Alderwick, Andrew Richards
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/
#define FLIP { s = ins & 0x40 ? &u->wst : &u->rst; }
#define JUMP(x) { if(m2) pc = (x); else pc += (Sint8)(x); }
#define POP1(o) { o = s->dat[--*sp]; }
#define POP2(o) { o = s->dat[--*sp] | (s->dat[--*sp] << 0x8); }
#define POPx(o) { if(m2) { POP2(o) } else POP1(o) }
#define PUSH1(y) { s->dat[s->ptr++] = (y); }
#define PUSH2(y) { tt = (y); s->dat[s->ptr++] = tt >> 0x8; s->dat[s->ptr++] = tt; }
#define PUSHx(y) { if(m2) { PUSH2(y) } else PUSH1(y) }
#define PEEK(o, x, r) { if(m2) { r = (x); o = ram[r++] << 8 | ram[r]; } else o = ram[(x)]; }
#define POKE(x, y, r) { if(m2) { r = (x); ram[r++] = y >> 8; ram[r] = y; } else ram[(x)] = (y); }
#define DEVR(o, p) { if(m2) { o = (emu_dei(u, p) << 8) | emu_dei(u, p + 1); } else o = emu_dei(u, p); }
#define DEVW(p, y) { if(m2) { emu_deo(u, p, y >> 8); emu_deo(u, p + 1, y); } else emu_deo(u, p, y); }
int
uxn_eval(Uxn *u, Uint16 pc)
{
Uint8 t, kp, *sp, *ram = u->ram;
Uint16 tt, a, b, c;
if(!pc || u->dev[0x0f]) return 0;
for(;;) {
Uint8 ins = ram[pc++];
/* 2 */ Uint8 m2 = ins & 0x20;
/* r */ Stack *s = ins & 0x40 ? &u->rst : &u->wst;
/* k */ if(ins & 0x80) kp = s->ptr, sp = &kp; else sp = &s->ptr;
switch(ins & 0x1f) {
case 0x00:
switch(ins) {
case 0x00: /* BRK */ return 1;
case 0x20: /* JCI */ POP1(b) if(!b) { pc += 2; break; }
case 0x40: /* JMI */ a = ram[pc++] << 8 | ram[pc++]; pc += a; break;
case 0x60: /* JSI */ PUSH2(pc + 2) a = ram[pc++] << 8 | ram[pc++]; pc += a; break;
case 0x80: case 0xc0: /* LIT */ PUSH1(ram[pc++]) break;
case 0xa0: case 0xe0: /* LIT2 */ PUSH1(ram[pc++]) PUSH1(ram[pc++]) break;
} break;
case 0x01: /* INC */ POPx(a) PUSHx(a + 1) break;
case 0x02: /* POP */ POPx(a) break;
case 0x03: /* NIP */ POPx(a) POPx(b) PUSHx(a) break;
case 0x04: /* SWP */ POPx(a) POPx(b) PUSHx(a) PUSHx(b) break;
case 0x05: /* ROT */ POPx(a) POPx(b) POPx(c) PUSHx(b) PUSHx(a) PUSHx(c) break;
case 0x06: /* DUP */ POPx(a) PUSHx(a) PUSHx(a) break;
case 0x07: /* OVR */ POPx(a) POPx(b) PUSHx(b) PUSHx(a) PUSHx(b) break;
case 0x08: /* EQU */ POPx(a) POPx(b) PUSH1(b == a) break;
case 0x09: /* NEQ */ POPx(a) POPx(b) PUSH1(b != a) break;
case 0x0a: /* GTH */ POPx(a) POPx(b) PUSH1(b > a) break;
case 0x0b: /* LTH */ POPx(a) POPx(b) PUSH1(b < a) break;
case 0x0c: /* JMP */ POPx(a) JUMP(a) break;
case 0x0d: /* JCN */ POPx(a) POP1(b) if(b) JUMP(a) break;
case 0x0e: /* JSR */ POPx(a) FLIP PUSH2(pc) JUMP(a) break;
case 0x0f: /* STH */ POPx(a) FLIP PUSHx(a) break;
case 0x10: /* LDZ */ POP1(a) PEEK(b, a, t) PUSHx(b) break;
case 0x11: /* STZ */ POP1(a) POPx(b) POKE(a, b, t) break;
case 0x12: /* LDR */ POP1(a) PEEK(b, pc + (Sint8)a, tt) PUSHx(b) break;
case 0x13: /* STR */ POP1(a) POPx(b) POKE(pc + (Sint8)a, b, tt) break;
case 0x14: /* LDA */ POP2(a) PEEK(b, a, tt) PUSHx(b) break;
case 0x15: /* STA */ POP2(a) POPx(b) POKE(a, b, tt) break;
case 0x16: /* DEI */ POP1(a) DEVR(b, a) PUSHx(b) break;
case 0x17: /* DEO */ POP1(a) POPx(b) DEVW(a, b) break;
case 0x18: /* ADD */ POPx(a) POPx(b) PUSHx(b + a) break;
case 0x19: /* SUB */ POPx(a) POPx(b) PUSHx(b - a) break;
case 0x1a: /* MUL */ POPx(a) POPx(b) PUSHx(b * a) break;
case 0x1b: /* DIV */ POPx(a) POPx(b) PUSHx(a ? b / a : 0) break;
case 0x1c: /* AND */ POPx(a) POPx(b) PUSHx(b & a) break;
case 0x1d: /* ORA */ POPx(a) POPx(b) PUSHx(b | a) break;
case 0x1e: /* EOR */ POPx(a) POPx(b) PUSHx(b ^ a) break;
case 0x1f: /* SFT */ POP1(a) POPx(b) PUSHx(b >> (a & 0xf) << (a >> 4)) break;
}
}
}

123
etc/cores/uxn-tnl.c

@ -1,123 +0,0 @@
#include "uxn.h"
/*
Copyright (u) 2022-2023 Devine Lu Linvega, Andrew Alderwick, Andrew Richards
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/
/* Registers
[ Z ][ Y ][ X ][ L ][ N ][ T ] <
[ . ][ . ][ . ][ H2 ][ . ] <
[ L2 ][ N2 ][ T2 ] <
*/
#define T *(s->dat + s->ptr)
#define N *(s->dat + (Uint8)(s->ptr - 1))
#define L *(s->dat + (Uint8)(s->ptr - 2))
#define X *(s->dat + (Uint8)(s->ptr - 3))
#define Y *(s->dat + (Uint8)(s->ptr - 4))
#define Z *(s->dat + (Uint8)(s->ptr - 5))
#define T2 (N << 8 | T)
#define H2 (L << 8 | N)
#define N2 (X << 8 | L)
#define L2 (Z << 8 | Y)
#define T2_(v) { r = (v); T = r; N = r >> 8; }
#define N2_(v) { r = (v); L = r; X = r >> 8; }
#define L2_(v) { r = (v); Y = r; Z = r >> 8; }
#define FLIP { s = ins & 0x40 ? &u->wst : &u->rst; }
#define SHIFT(y) { s->ptr += (y); }
#define SET(x, y) { SHIFT((ins & 0x80) ? x + y : y) }
int
uxn_eval(Uxn *u, Uint16 pc)
{
Uint16 t, n, l, r;
Uint8 *ram = u->ram, *rr;
if(!pc || u->dev[0x0f]) return 0;
for(;;) {
Uint8 ins = ram[pc++];
Stack *s = ins & 0x40 ? &u->rst : &u->wst;
switch(ins & 0x3f) {
/* IMM */
case 0x00: case 0x20:
switch(ins) {
case 0x00: /* BRK */ return 1;
case 0x20: /* JCI */ t=T; SHIFT(-1) if(!t) { pc += 2; break; } /* fall-through */
case 0x40: /* JMI */ rr = ram + pc; pc += 2 + PEEK2(rr); break;
case 0x60: /* JSI */ SHIFT( 2) rr = ram + pc; pc += 2; T2_(pc); pc += PEEK2(rr); break;
case 0x80: /* LIT */ case 0xc0: SHIFT( 1) T = ram[pc++]; break;
case 0xa0: /* LIT2 */ case 0xe0: SHIFT( 2) N = ram[pc++]; T = ram[pc++]; break;
} break;
/* ALU */
case 0x01: /* INC */ t=T; SET(1, 0) T = t + 1; break;
case 0x21: /* INC2 */ t=T2; SET(2, 0) T2_(t + 1) break;
case 0x02: /* POP */ SET(1,-1) break;
case 0x22: /* POP2 */ SET(2,-2) break;
case 0x03: /* NIP */ t=T; SET(2,-1) T = t; break;
case 0x23: /* NIP2 */ t=T2; SET(4,-2) T2_(t) break;
case 0x04: /* SWP */ t=T;n=N; SET(2, 0) T = n; N = t; break;
case 0x24: /* SWP2 */ t=T2;n=N2; SET(4, 0) T2_(n) N2_(t) break;
case 0x05: /* ROT */ t=T;n=N;l=L; SET(3, 0) T = l; N = t; L = n; break;
case 0x25: /* ROT2 */ t=T2;n=N2;l=L2; SET(6, 0) T2_(l) N2_(t) L2_(n) break;
case 0x06: /* DUP */ t=T; SET(1, 1) T = t; N = t; break;
case 0x26: /* DUP2 */ t=T2; SET(2, 2) T2_(t) N2_(t) break;
case 0x07: /* OVR */ t=T;n=N; SET(2, 1) T = n; N = t; L = n; break;
case 0x27: /* OVR2 */ t=T2;n=N2; SET(4, 2) T2_(n) N2_(t) L2_(n) break;
case 0x08: /* EQU */ t=T;n=N; SET(2,-1) T = n == t; break;
case 0x28: /* EQU2 */ t=T2;n=N2; SET(4,-3) T = n == t; break;
case 0x09: /* NEQ */ t=T;n=N; SET(2,-1) T = n != t; break;
case 0x29: /* NEQ2 */ t=T2;n=N2; SET(4,-3) T = n != t; break;
case 0x0a: /* GTH */ t=T;n=N; SET(2,-1) T = n > t; break;
case 0x2a: /* GTH2 */ t=T2;n=N2; SET(4,-3) T = n > t; break;
case 0x0b: /* LTH */ t=T;n=N; SET(2,-1) T = n < t; break;
case 0x2b: /* LTH2 */ t=T2;n=N2; SET(4,-3) T = n < t; break;
case 0x0c: /* JMP */ t=T; SET(1,-1) pc += (Sint8)t; break;
case 0x2c: /* JMP2 */ t=T2; SET(2,-2) pc = t; break;
case 0x0d: /* JCN */ t=T;n=N; SET(2,-2) if(n) pc += (Sint8)t; break;
case 0x2d: /* JCN2 */ t=T2;n=L; SET(3,-3) if(n) pc = t; break;
case 0x0e: /* JSR */ t=T; SET(1,-1) FLIP SHIFT(2) T2_(pc) pc += (Sint8)t; break;
case 0x2e: /* JSR2 */ t=T2; SET(2,-2) FLIP SHIFT(2) T2_(pc) pc = t; break;
case 0x0f: /* STH */ t=T; SET(1,-1) FLIP SHIFT(1) T = t; break;
case 0x2f: /* STH2 */ t=T2; SET(2,-2) FLIP SHIFT(2) T2_(t) break;
case 0x10: /* LDZ */ t=T; SET(1, 0) T = ram[t]; break;
case 0x30: /* LDZ2 */ t=T; SET(1, 1) N = ram[t++]; T = ram[(Uint8)t]; break;
case 0x11: /* STZ */ t=T;n=N; SET(2,-2) ram[t] = n; break;
case 0x31: /* STZ2 */ t=T;n=H2; SET(3,-3) ram[t++] = n >> 8; ram[(Uint8)t] = n; break;
case 0x12: /* LDR */ t=T; SET(1, 0) r = pc + (Sint8)t; T = ram[r]; break;
case 0x32: /* LDR2 */ t=T; SET(1, 1) r = pc + (Sint8)t; N = ram[r++]; T = ram[r]; break;
case 0x13: /* STR */ t=T;n=N; SET(2,-2) r = pc + (Sint8)t; ram[r] = n; break;
case 0x33: /* STR2 */ t=T;n=H2; SET(3,-3) r = pc + (Sint8)t; ram[r++] = n >> 8; ram[r] = n; break;
case 0x14: /* LDA */ t=T2; SET(2,-1) T = ram[t]; break;
case 0x34: /* LDA2 */ t=T2; SET(2, 0) N = ram[t++]; T = ram[t]; break;
case 0x15: /* STA */ t=T2;n=L; SET(3,-3) ram[t] = n; break;
case 0x35: /* STA2 */ t=T2;n=N2; SET(4,-4) ram[t++] = n >> 8; ram[t] = n; break;
case 0x16: /* DEI */ t=T; SET(1, 0) T = emu_dei(u, t); break;
case 0x36: /* DEI2 */ t=T; SET(1, 1) N = emu_dei(u, t++); T = emu_dei(u, t); break;
case 0x17: /* DEO */ t=T;n=N; SET(2,-2) emu_deo(u, t, n); break;
case 0x37: /* DEO2 */ t=T;n=N;l=L; SET(3,-3) emu_deo(u, t++, l); emu_deo(u, t, n); break;
case 0x18: /* ADD */ t=T;n=N; SET(2,-1) T = n + t; break;
case 0x38: /* ADD2 */ t=T2;n=N2; SET(4,-2) T2_(n + t) break;
case 0x19: /* SUB */ t=T;n=N; SET(2,-1) T = n - t; break;
case 0x39: /* SUB2 */ t=T2;n=N2; SET(4,-2) T2_(n - t) break;
case 0x1a: /* MUL */ t=T;n=N; SET(2,-1) T = n * t; break;
case 0x3a: /* MUL2 */ t=T2;n=N2; SET(4,-2) T2_(n * t) break;
case 0x1b: /* DIV */ t=T;n=N; SET(2,-1) T = t ? n / t : 0; break;
case 0x3b: /* DIV2 */ t=T2;n=N2; SET(4,-2) T2_(t ? n / t : 0) break;
case 0x1c: /* AND */ t=T;n=N; SET(2,-1) T = n & t; break;
case 0x3c: /* AND2 */ t=T2;n=N2; SET(4,-2) T2_(n & t) break;
case 0x1d: /* ORA */ t=T;n=N; SET(2,-1) T = n | t; break;
case 0x3d: /* ORA2 */ t=T2;n=N2; SET(4,-2) T2_(n | t) break;
case 0x1e: /* EOR */ t=T;n=N; SET(2,-1) T = n ^ t; break;
case 0x3e: /* EOR2 */ t=T2;n=N2; SET(4,-2) T2_(n ^ t) break;
case 0x1f: /* SFT */ t=T;n=N; SET(2,-1) T = n >> (t & 0xf) << (t >> 4); break;
case 0x3f: /* SFT2 */ t=T;n=H2; SET(3,-1) T2_(n >> (t & 0xf) << (t >> 4)) break;
}
}
}

16
etc/utos/build.sh

@ -1,16 +0,0 @@
#!/bin/bash
echo "Formatting.."
clang-format -i utos.c
echo "Cleaning.."
rm -f ../../bin/utos
echo "Building.."
mkdir -p ../../bin
cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined -lm utos.c -o ../../bin/utos
echo "Running.."
../../bin/utos ../../projects/sounds/pad1.ss8 ../../projects/sounds/pad1.pcm
echo "Done."

39
etc/utos/utos.c

@ -1,39 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
/*
Copyright (c) 2020 Devine Lu Linvega
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/
typedef unsigned char Uint8;
typedef signed char Sint8;
typedef unsigned short Uint16;
typedef signed short Sint16;
int
main(int argc, char **argv)
{
FILE *f;
Uint8 *buffer;
Uint16 filelen, i;
if(argc < 2 || !(f = fopen(argv[1], "rb")))
return 1;
fseek(f, 0, SEEK_END);
filelen = ftell(f);
rewind(f);
buffer = (Uint8 *)malloc(filelen * sizeof(Uint8));
fread(buffer, filelen, 1, f);
fclose(f);
for(i = 0; i < filelen; ++i)
buffer[i] += 0x80;
printf("\n\n");
fwrite(buffer, filelen, 1, fopen(argv[2], "wb"));
return 0;
}

103
etc/uxambly-translate.moon

@ -1,103 +0,0 @@
-- Used for porting Uxntal code for use with the old assembler
-- in commit 82f7103a55c21b13f898b20e5d1e174e501bc825 with the
-- assembler that replaced it straight afterwards.
import P, R, S, C, Ct, Cp, V from require 'lpeg'
local labels, filename
opcode_translate =
LDZ2: 'LDA'
STZ2: 'STA'
LDR: 'LDZ2'
STR: 'STZ2'
LDR2: 'LDA2'
STR2: 'STA2'
grammar = P {
'file'
file: Ct(V'ows' * (V'atom' * V'ows') ^ 0) * Cp!
ws: C S' \n\t' ^ 1
ows: C S' \n\t' ^ 0
atom: V'opcode' + V'comment' + V'variable' + V'addr' + V'literal' + V'setter' + V'getter' + V'short' + V'labeldef' + V'relative' + V'sublabel' + V'data' + V'macro' + V'macroref' + V'rawshort'
comment: C P'(' * (1-V'ws'*P')') ^ 0 * V'ws' * P')'
variable: (P';' / -> '@') * C(V'name') * V'ws' * (P'{' / ->'[') * V'ws' * ((P'' / -> '&') * C(V'name') * V'ws' * (P'' / -> '$') * C(V'name') * V'ws') ^ 0 * (P'}' / -> ']') / (...) ->
var = select 2, ...
r, w = if var\sub(1, 1) == var\sub(1, 1)\upper!
' DEI', ' DEO'
else
' LDZ', ' STZ'
for i = 7, select('#', ...), 6
k = select i, ...
rr, ww = if '2' == select i + 3, ...
r .. '2', w .. '2'
else
r, w
labels['~' .. var .. '.' .. k] = '.' .. var .. '/' .. k .. rr
labels['=' .. var .. '.' .. k] = '.' .. var .. '/' .. k .. ww
if i == 7
labels['~' .. var] = '.' .. var .. rr
labels['=' .. var] = '.' .. var .. ww
...
name: R('az', 'AZ', '09', '__', '--', '++', '**', '//', '??') ^ 1
addr: C(P'|') * (C(V'hex') / (i) ->
if i == '0200'
return '0100'
if i\match '^01..$'
return i\sub 3
return i
)
literal: C P'#' * V'hex'
hex: R('09', 'af', 'AF') ^ 1
setter: C(P'=' * V'label') / (s) ->
if not labels[s]
error 'label not found: %q in %s'\format s, filename
return labels[s]
getter: C(P'~' * V'label') / (s) ->
if not labels[s]
error 'label not found: %q in %s'\format s, filename
return labels[s]
label: R('az', 'AZ', '09', '__', '--', '..', '$$', ']]', '))', '@@', '""', ',,', '##', '||', '{{', '}}', '%%', ';;', '^^', '~~', '==', '//') ^ 1
short: (P',' / -> ';') * (C(V'label') / (s) -> (s\gsub '%$', '&'))
rawshort: (P'.' / -> ':') * (C(V'label') / (s) -> (s\gsub '%$', '&'))
opcode: (C(R'AZ' * R'AZ' * R'AZ' * P'2' ^ -1) / (s) -> opcode_translate[s] or s) * C P'r' ^ -1 * #V'ws'
labeldef: C P'@' * V'label'
relative: (P'^' / -> ',') * (C(V'label') / (s) -> (s\gsub '%$', '&'))
sublabel: (P'$' / -> '&') * (C(V'label') / (s) -> (s\gsub '%$', '&'))
data: C(P'[') * V'ws' * (V'data_item' * V'ws') ^ 0 * C(P']')
macro: C(P'%' * V'name' * V'ws' * P'{') * V'ws' * (V'atom' * V'ows') ^ 0 * C P'}'
macroref: C V'name'
data_item: C(V'hex' * #V'ws') + V'data_string'
data_string: C((1 - S' \n\t') ^ 1 - P']') / (s) -> '"', s
}
translate = (_filename) ->
filename = _filename
labels = {}
f = assert io.open filename
contents = f\read '*a'
f\close!
t, len = grammar\match contents
if len <= #contents
print '\027[32m%s\027[0;1m%s\027[0m'\format contents\sub(len - 100, len - 1), contents\sub(len, len + 100)
error 'no match'
filename = filename\gsub 'attic', 'auto'
f = assert io.open filename, 'w'
f\write table.concat(t)
f\close!
f = assert io.popen 'bin/assembler %s bin/boot.rom'\format filename
for l in f\lines!
print l
if l == 'Error: Assembly[Failed]'
os.exit 1
f\close!
os.exit 0
translate 'attic/software/assembler.tal'
os.exit 0
translate 'attic/tests/opcodes.tal'
translate 'attic/tests/basics.tal'
-- for k, v in pairs t
-- print k
Loading…
Cancel
Save