... | ... |
@@ -1,10 +1,10 @@ |
1 | 1 |
# Uxn |
2 | 2 |
|
3 |
-A [stack-based VM](https://wiki.xxiivv.com/site/uxn.html), written in ANSI C. |
|
3 |
+An [8-bit stack-based computer](https://wiki.xxiivv.com/site/uxn.html), written in ANSI C. |
|
4 | 4 |
|
5 | 5 |
## Build |
6 | 6 |
|
7 |
-To build the Uxn emulator, you must have [SDL2](https://wiki.libsdl.org/). |
|
7 |
+To build the Uxn emulator, you must have [SDL2](https://wiki.libsdl.org/) and [Portmidi](http://portmedia.sourceforge.net/portmidi/). |
|
8 | 8 |
|
9 | 9 |
```sh |
10 | 10 |
./build.sh |
... | ... |
@@ -34,7 +34,7 @@ Read more in the [Uxambly Guide](https://wiki.xxiivv.com/site/uxambly.html). |
34 | 34 |
|
35 | 35 |
|0100 ( -> ) |
36 | 36 |
|
37 |
- ;hello-word ;print JSR2 |
|
37 |
+ ;hello-word ,print JSR |
|
38 | 38 |
|
39 | 39 |
BRK |
40 | 40 |
|
... | ... |
@@ -54,11 +54,6 @@ RTN |
54 | 54 |
## TODOs |
55 | 55 |
|
56 | 56 |
- Shortcut to export/import disk state |
57 |
-- Implement Uxambly REPL |
|
58 |
-- Load disks at a different place than 0x0000. |
|
59 |
-- Curl device? 8-bit web browser? |
|
60 |
- - Replace LTS/GTS? `LTS = #80 ADD SWP #80 ADD SWP LTH` |
|
61 |
- - `#80 ADD SWP #80 ADD GTH` |
|
62 | 57 |
|
63 | 58 |
## Palettes |
64 | 59 |
|
... | ... |
@@ -2,7 +2,6 @@ |
2 | 2 |
|
3 | 3 |
%++ { #0001 ADD2 } |
4 | 4 |
%-- { #0001 SUB2 } |
5 |
-%2/ { #0002 DIV2 } |
|
6 | 5 |
|
7 | 6 |
( devices ) |
8 | 7 |
|
... | ... |
@@ -29,8 +28,8 @@ |
29 | 28 |
;on-frame .Screen/vector DEO2 |
30 | 29 |
|
31 | 30 |
( set origin ) |
32 |
- .Screen/width DEI2 2/ .Screen/x DEO2 |
|
33 |
- .Screen/height DEI2 2/ .Screen/y DEO2 |
|
31 |
+ .Screen/width DEI2 #0002 DIV2 .Screen/x DEO2 |
|
32 |
+ .Screen/height DEI2 #0002 DIV2 .Screen/y DEO2 |
|
34 | 33 |
|
35 | 34 |
;default_icn .Screen/addr DEO2 |
36 | 35 |
#31 .Screen/color DEO |
... | ... |
@@ -6,6 +6,8 @@ |
6 | 6 |
%SCALEX { #0002 DIV2 .Screen/width DEI2 #0002 DIV2 ADD2 #0040 SUB2 } |
7 | 7 |
%SCALEY { #0002 DIV2 .Screen/height DEI2 #0002 DIV2 ADD2 #0040 SUB2 } |
8 | 8 |
%12HOURS { DUP #0c GTH #0c MUL SUB } |
9 |
+%LTS2 { #8000 ADD2 SWP2 #8000 ADD2 GTH2 } |
|
10 |
+%GTS2 { #8000 ADD2 SWP2 #8000 ADD2 LTH2 } |
|
9 | 11 |
|
10 | 12 |
( devices ) |
11 | 13 |
|
... | ... |
@@ -1,7 +1,9 @@ |
1 | 1 |
( dev/mouse ) |
2 | 2 |
|
3 |
-%RTN { JMP2r } |
|
4 |
-%ABS2 { DUP2 #000f SFT2 EQU #04 JNZ #ffff MUL2 }. |
|
3 |
+%RTN { JMP2r } |
|
4 |
+%ABS2 { DUP2 #000f SFT2 EQU #04 JNZ #ffff MUL2 } |
|
5 |
+%LTS2 { #8000 ADD2 SWP2 #8000 ADD2 GTH2 } |
|
6 |
+%GTS2 { #8000 ADD2 SWP2 #8000 ADD2 LTH2 } |
|
5 | 7 |
|
6 | 8 |
( devices ) |
7 | 9 |
|
... | ... |
@@ -93,15 +95,15 @@ RTN |
93 | 95 |
( load ) .color POK .line/y0 POK2 .line/x0 POK2 .line/y POK2 .line/x POK2 |
94 | 96 |
.line/x0 PEK2 .line/x PEK2 SUB2 ABS2 .line/dx POK2 |
95 | 97 |
.line/y0 PEK2 .line/y PEK2 SUB2 ABS2 #0000 SWP2 SUB2 .line/dy POK2 |
96 |
- #ffff #00 .line/x PEK2 .line/x0 PEK2 LTS2 #0002 MUL2 ADD2 .line/sx POK2 |
|
97 |
- #ffff #00 .line/y PEK2 .line/y0 PEK2 LTS2 #0002 MUL2 ADD2 .line/sy POK2 |
|
98 |
+ #ffff #00 .line/x PEK2 .line/x0 PEK2 LTS2 #0002 MUL2 ADD2 .line/sx POK2 |
|
99 |
+ #ffff #00 .line/y PEK2 .line/y0 PEK2 LTS2 #0002 MUL2 ADD2 .line/sy POK2 |
|
98 | 100 |
.line/dx PEK2 .line/dy PEK2 ADD2 .line/e1 POK2 |
99 | 101 |
&loop |
100 |
- ( draw ) |
|
101 | 102 |
.line/x PEK2 .Screen/x DEO2 |
102 | 103 |
.line/y PEK2 .Screen/y DEO2 |
103 | 104 |
.color PEK .Screen/color DEO |
104 |
- .line/x PEK2 .line/x0 PEK2 EQU2 .line/y PEK2 .line/y0 PEK2 EQU2 #0101 EQU2 ,&end JNZ |
|
105 |
+ [ .line/x PEK2 .line/x0 PEK2 EQU2 ] |
|
106 |
+ [ .line/y PEK2 .line/y0 PEK2 EQU2 ] #0101 EQU2 ,&end JNZ |
|
105 | 107 |
.line/e1 PEK2 #0002 MUL2 .line/e2 POK2 |
106 | 108 |
.line/e2 PEK2 .line/dy PEK2 LTS2 ,&skipy JNZ |
107 | 109 |
.line/e1 PEK2 .line/dy PEK2 ADD2 .line/e1 POK2 |
... | ... |
@@ -111,7 +113,7 @@ RTN |
111 | 113 |
.line/e1 PEK2 .line/dx PEK2 ADD2 .line/e1 POK2 |
112 | 114 |
.line/y PEK2 .line/sy PEK2 ADD2 .line/y POK2 |
113 | 115 |
&skipx |
114 |
- ,&loop JMP |
|
116 |
+ ;&loop JMP2 |
|
115 | 117 |
&end |
116 | 118 |
|
117 | 119 |
RTN |
... | ... |
@@ -41,8 +41,8 @@ Program p; |
41 | 41 |
|
42 | 42 |
char ops[][4] = { |
43 | 43 |
"BRK", "LIT", "NOP", "POP", "DUP", "SWP", "OVR", "ROT", |
44 |
- "EQU", "NEQ", "GTH", "LTH", "GTS", "LTS", "DEI", "DEO", |
|
45 |
- "PEK", "POK", "GET", "PUT", "JMP", "JNZ", "JSR", "STH", |
|
44 |
+ "EQU", "NEQ", "GTH", "LTH", "JMP", "JNZ", "JSR", "STH", |
|
45 |
+ "PEK", "POK", "GET", "PUT", "---", "---", "DEI", "DEO", |
|
46 | 46 |
"ADD", "SUB", "MUL", "DIV", "AND", "ORA", "EOR", "SFT" |
47 | 47 |
}; |
48 | 48 |
|
... | ... |
@@ -44,19 +44,17 @@ void op_equ(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); push8(u->src, b |
44 | 44 |
void op_neq(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); push8(u->src, b != a); } |
45 | 45 |
void op_gth(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); push8(u->src, b > a); } |
46 | 46 |
void op_lth(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); push8(u->src, b < a); } |
47 |
-void op_gts(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); push8(u->src, (Sint8)b > (Sint8)a); } |
|
48 |
-void op_lts(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); push8(u->src, (Sint8)b < (Sint8)a); } |
|
49 |
-void op_dei(Uxn *u) { Uint8 a = pop8(u->src); push8(u->src, devpeek8(&u->dev[a >> 4], a)); } |
|
50 |
-void op_deo(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); devpoke8(&u->dev[a >> 4], a, b); } |
|
47 |
+void op_jmp(Uxn *u) { Uint8 a = pop8(u->src); u->ram.ptr += (Sint8)a; } |
|
48 |
+void op_jnz(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); if (b) u->ram.ptr += (Sint8)a; } |
|
49 |
+void op_jsr(Uxn *u) { Uint8 a = pop8(u->src); push16(u->dst, u->ram.ptr); u->ram.ptr += (Sint8)a; } |
|
50 |
+void op_sth(Uxn *u) { Uint8 a = pop8(u->src); push8(u->dst, a); } |
|
51 | 51 |
/* Memory */ |
52 | 52 |
void op_pek(Uxn *u) { Uint8 a = pop8(u->src); push8(u->src, mempeek8(u->ram.dat, a)); } |
53 | 53 |
void op_pok(Uxn *u) { Uint8 a = pop8(u->src); Uint8 b = pop8(u->src); mempoke8(u->ram.dat, a, b); } |
54 | 54 |
void op_get(Uxn *u) { Uint16 a = pop16(u->src); push8(u->src, mempeek8(u->ram.dat, a)); } |
55 | 55 |
void op_put(Uxn *u) { Uint16 a = pop16(u->src); Uint8 b = pop8(u->src); mempoke8(u->ram.dat, a, b); } |
56 |
-void op_jmp(Uxn *u) { Uint8 a = pop8(u->src); u->ram.ptr += (Sint8)a; } |
|
57 |
-void op_jnz(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); if (b) u->ram.ptr += (Sint8)a; } |
|
58 |
-void op_jsr(Uxn *u) { Uint8 a = pop8(u->src); push16(u->dst, u->ram.ptr); u->ram.ptr += (Sint8)a; } |
|
59 |
-void op_sth(Uxn *u) { Uint8 a = pop8(u->src); push8(u->dst, a); } |
|
56 |
+void op_dei(Uxn *u) { Uint8 a = pop8(u->src); push8(u->src, devpeek8(&u->dev[a >> 4], a)); } |
|
57 |
+void op_deo(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); devpoke8(&u->dev[a >> 4], a, b); } |
|
60 | 58 |
/* Arithmetic */ |
61 | 59 |
void op_add(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); push8(u->src, b + a); } |
62 | 60 |
void op_sub(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); push8(u->src, b - a); } |
... | ... |
@@ -78,19 +76,17 @@ void op_equ16(Uxn *u) { Uint16 a = pop16(u->src), b = pop16(u->src); push8(u->sr |
78 | 76 |
void op_neq16(Uxn *u) { Uint16 a = pop16(u->src), b = pop16(u->src); push8(u->src, b != a); } |
79 | 77 |
void op_gth16(Uxn *u) { Uint16 a = pop16(u->src), b = pop16(u->src); push8(u->src, b > a); } |
80 | 78 |
void op_lth16(Uxn *u) { Uint16 a = pop16(u->src), b = pop16(u->src); push8(u->src, b < a); } |
81 |
-void op_gts16(Uxn *u) { Uint16 a = pop16(u->src), b = pop16(u->src); push8(u->src, (Sint16)b > (Sint16)a); } |
|
82 |
-void op_lts16(Uxn *u) { Uint16 a = pop16(u->src), b = pop16(u->src); push8(u->src, (Sint16)b < (Sint16)a); } |
|
83 |
-void op_dei16(Uxn *u) { Uint8 a = pop8(u->src); push16(u->src, devpeek16(&u->dev[a >> 4], a)); } |
|
84 |
-void op_deo16(Uxn *u) { Uint8 a = pop8(u->src); Uint16 b = pop16(u->src); devpoke16(&u->dev[a >> 4], a, b); } |
|
79 |
+void op_jmp16(Uxn *u) { u->ram.ptr = pop16(u->src); } |
|
80 |
+void op_jnz16(Uxn *u) { Uint16 a = pop16(u->src); Uint8 b = pop8(u->src); if (b) u->ram.ptr = a; } |
|
81 |
+void op_jsr16(Uxn *u) { push16(u->dst, u->ram.ptr); u->ram.ptr = pop16(u->src); } |
|
82 |
+void op_sth16(Uxn *u) { Uint16 a = pop16(u->src); push16(u->dst, a); } |
|
85 | 83 |
/* Memory(16-bits) */ |
86 | 84 |
void op_pek16(Uxn *u) { Uint8 a = pop8(u->src); push16(u->src, mempeek16(u->ram.dat, a)); } |
87 | 85 |
void op_pok16(Uxn *u) { Uint8 a = pop8(u->src); Uint16 b = pop16(u->src); mempoke16(u->ram.dat, a, b); } |
88 | 86 |
void op_get16(Uxn *u) { Uint16 a = pop16(u->src); push16(u->src, mempeek16(u->ram.dat, a)); } |
89 | 87 |
void op_put16(Uxn *u) { Uint16 a = pop16(u->src); Uint16 b = pop16(u->src); mempoke16(u->ram.dat, a, b); } |
90 |
-void op_jmp16(Uxn *u) { u->ram.ptr = pop16(u->src); } |
|
91 |
-void op_jnz16(Uxn *u) { Uint16 a = pop16(u->src); Uint8 b = pop8(u->src); if (b) u->ram.ptr = a; } |
|
92 |
-void op_jsr16(Uxn *u) { push16(u->dst, u->ram.ptr); u->ram.ptr = pop16(u->src); } |
|
93 |
-void op_sth16(Uxn *u) { Uint16 a = pop16(u->src); push16(u->dst, a); } |
|
88 |
+void op_dei16(Uxn *u) { Uint8 a = pop8(u->src); push16(u->src, devpeek16(&u->dev[a >> 4], a)); } |
|
89 |
+void op_deo16(Uxn *u) { Uint8 a = pop8(u->src); Uint16 b = pop16(u->src); devpoke16(&u->dev[a >> 4], a, b); } |
|
94 | 90 |
/* Arithmetic(16-bits) */ |
95 | 91 |
void op_add16(Uxn *u) { Uint16 a = pop16(u->src), b = pop16(u->src); push16(u->src, b + a); } |
96 | 92 |
void op_sub16(Uxn *u) { Uint16 a = pop16(u->src), b = pop16(u->src); push16(u->src, b - a); } |
... | ... |
@@ -103,13 +99,13 @@ void op_sft16(Uxn *u) { Uint16 a = pop16(u->src), b = pop16(u->src); push16(u->s |
103 | 99 |
|
104 | 100 |
void (*ops[])(Uxn *u) = { |
105 | 101 |
op_brk, op_lit, op_nop, op_pop, op_dup, op_swp, op_ovr, op_rot, |
106 |
- op_equ, op_neq, op_gth, op_lth, op_gts, op_lts, op_dei, op_deo, |
|
107 |
- op_pek, op_pok, op_get, op_put, op_jmp, op_jnz, op_jsr, op_sth, |
|
102 |
+ op_equ, op_neq, op_gth, op_lth, op_jmp, op_jnz, op_jsr, op_sth, |
|
103 |
+ op_pek, op_pok, op_get, op_put, op_nop, op_nop, op_dei, op_deo, |
|
108 | 104 |
op_add, op_sub, op_mul, op_div, op_and, op_ora, op_eor, op_sft, |
109 | 105 |
/* 16-bit */ |
110 | 106 |
op_brk, op_lit16, op_nop, op_pop16, op_dup16, op_swp16, op_ovr16, op_rot16, |
111 |
- op_equ16, op_neq16, op_gth16, op_lth16, op_gts16, op_lts16, op_dei16, op_deo16, |
|
112 |
- op_pek16, op_pok16, op_get16, op_put16, op_jmp16, op_jnz16, op_jsr16, op_sth16, |
|
107 |
+ op_equ16, op_neq16, op_gth16, op_lth16, op_jmp16, op_jnz16, op_jsr16, op_sth16, |
|
108 |
+ op_pek16, op_pok16, op_get16, op_put16, op_nop, op_nop, op_dei16, op_deo16, |
|
113 | 109 |
op_add16, op_sub16, op_mul16, op_div16, op_and16, op_ora16, op_eor16, op_sft16 |
114 | 110 |
}; |
115 | 111 |
|