Browse code

Improved uxncli and moved all demos into examples

neauoire authored on 26/05/2021 17:02:13
Showing 25 changed files
... ...
@@ -1,6 +1,6 @@
1 1
 # Uxn
2 2
 
3
-An assembler and emulator for a [tiny stack-based computer](https://wiki.xxiivv.com/site/uxn.html), written in ANSI C. 
3
+An assembler and emulator for the [Uxn stack-machine](https://wiki.xxiivv.com/site/uxn.html), written in ANSI C. 
4 4
 
5 5
 ## Build
6 6
 
... ...
@@ -11,7 +11,6 @@ To build the Uxn emulator, you must have [SDL2](https://wiki.libsdl.org/).
11 11
 ```sh
12 12
 ./build.sh 
13 13
 	--debug # Add debug flags to compiler
14
-	--cli # Run rom without graphics
15 14
 ```
16 15
 
17 16
 ### Plan 9 
... ...
@@ -22,8 +21,7 @@ To build the Uxn emulator on [9front](http://9front.org/), via [npe](https://git
22 21
 mk
23 22
 ```
24 23
 
25
-If the build fails on 9front because of missing headers or functions,
26
-try again after `rm -r /sys/include/npe`.
24
+If the build fails on 9front because of missing headers or functions, try again after `rm -r /sys/include/npe`.
27 25
 
28 26
 ## Getting Started
29 27
 
... ...
@@ -36,7 +34,7 @@ Begin by building the assembler and emulator by running the build script. The as
36 34
 The following command will create an Uxn-compatible rom from an [uxambly file](https://wiki.xxiivv.com/site/uxambly.html), point to a different usm file in `/projects` to assemble a different rom. 
37 35
 
38 36
 ```
39
-bin/uxnasm projects/demos/life.usm bin/life.rom
37
+bin/uxnasm projects/examples/demos/life.usm bin/life.rom
40 38
 ```
41 39
 
42 40
 To start the rom, point the emulator to the newly created rom:
... ...
@@ -45,11 +43,11 @@ To start the rom, point the emulator to the newly created rom:
45 43
 bin/uxnemu bin/life.rom
46 44
 ```
47 45
 
48
-You can find additional roms [here](https://sr.ht/~rabbits/uxn/sources).
46
+You can also use the emulator without graphics by using `uxncli`. You can find additional roms [here](https://sr.ht/~rabbits/uxn/sources).
49 47
 
50 48
 ## Emulator Controls
51 49
 
52
-- `ctrl+h` toggle debugger
50
+- `ctrl+h` toggle inspector
53 51
 - `alt+h` toggle zoom
54 52
 
55 53
 ## Need a hand?
... ...
@@ -9,14 +9,14 @@ clang-format -i src/devices/apu.h
9 9
 clang-format -i src/devices/apu.c
10 10
 clang-format -i src/devices/mpu.h
11 11
 clang-format -i src/devices/mpu.c
12
-clang-format -i src/assembler.c
13
-clang-format -i src/emulator.c
14
-clang-format -i src/debugger.c
12
+clang-format -i src/uxnasm.c
13
+clang-format -i src/uxnemu.c
14
+clang-format -i src/uxncli.c
15 15
 
16 16
 echo "Cleaning.."
17 17
 rm -f ./bin/uxnasm
18 18
 rm -f ./bin/uxnemu
19
-rm -f ./bin/debugger
19
+rm -f ./bin/uxncli
20 20
 rm -f ./bin/boot.rom
21 21
 
22 22
 echo "Building.."
... ...
@@ -24,13 +24,13 @@ mkdir -p bin
24 24
 if [ "${1}" = '--debug' ]; 
25 25
 then
26 26
 	echo "[debug]"
27
-    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 src/assembler.c -o bin/uxnasm
28
-	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 src/uxn.c src/devices/ppu.c src/devices/apu.c src/devices/mpu.c src/emulator.c -L/usr/local/lib -lSDL2 -o bin/uxnemu
29
-    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 src/uxn.c src/debugger.c -o bin/debugger
27
+    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 src/uxnasm.c -o bin/uxnasm
28
+	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 src/uxn.c src/devices/ppu.c src/devices/apu.c src/devices/mpu.c src/uxnemu.c -L/usr/local/lib -lSDL2 -o bin/uxnemu
29
+    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 src/uxn.c src/uxncli.c -o bin/uxncli
30 30
 else
31
-	cc src/assembler.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o bin/uxnasm
32
-	cc src/uxn-fast.c src/debugger.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o bin/debugger
33
-	cc src/uxn-fast.c src/devices/ppu.c src/devices/apu.c src/devices/mpu.c src/emulator.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -L/usr/local/lib -lSDL2 -o bin/uxnemu
31
+	cc src/uxnasm.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o bin/uxnasm
32
+	cc src/uxn-fast.c src/uxncli.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o bin/uxncli
33
+	cc src/uxn-fast.c src/devices/ppu.c src/devices/apu.c src/devices/mpu.c src/uxnemu.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -L/usr/local/lib -lSDL2 -o bin/uxnemu
34 34
 fi
35 35
 
36 36
 echo "Installing.."
... ...
@@ -38,19 +38,14 @@ if [ -d "$HOME/bin" ] && [ -e ./bin/uxnemu ] && [ -e ./bin/uxnasm ]
38 38
 then
39 39
 	cp ./bin/uxnemu $HOME/bin
40 40
 	cp ./bin/uxnasm $HOME/bin
41
+	cp ./bin/uxncli $HOME/bin
41 42
     echo "Installed in $HOME/bin" 
42 43
 fi
43 44
 
44 45
 echo "Assembling.."
45
-./bin/uxnasm projects/demos/piano.usm bin/boot.rom
46
+./bin/uxnasm projects/examples/demos/piano.usm bin/piano.rom
46 47
 
47 48
 echo "Running.."
48
-if [ "${2}" = '--cli' ]; 
49
-then
50
-	echo "[cli]"
51
-	./bin/debugger bin/boot.rom
52
-else
53
-	./bin/uxnemu bin/boot.rom
54
-fi
49
+./bin/uxnemu bin/piano.rom
55 50
 
56 51
 echo "Done."
... ...
@@ -22,7 +22,7 @@ EOD
22 22
 
23 23
 expect_failure() {
24 24
     cat > 'in.usm'
25
-    if ../bin/debugger asma.rom > asma.log 2>/dev/null || ! grep -qF "${1}" asma.log; then
25
+    if ../bin/uxncli asma.rom > asma.log 2>/dev/null || ! grep -qF "${1}" asma.log; then
26 26
         echo "error: asma didn't report error ${1} in faulty code"
27 27
 		tail asma.log
28 28
         exit 1
... ...
@@ -44,7 +44,7 @@ find ../projects -type f -name '*.usm' -not -name 'blank.usm' | sort | while rea
44 44
 	xxd "uxnasm-${BN}.rom" > "uxnasm-${BN}.hex"
45 45
 
46 46
 	cp "${F}" 'in.usm'
47
-	if ! ../bin/debugger asma.rom > asma.log; then
47
+	if ! ../bin/uxncli asma.rom > asma.log; then
48 48
 		echo "error: asma failed to assemble ${F}, while uxnasm succeeded"
49 49
 		tail asma.log
50 50
 		exit 1
... ...
@@ -23,7 +23,7 @@ local trees = {
23 23
 local opcodes_in_order = { }
24 24
 do
25 25
   local wanted = false
26
-  for l in assert(io.lines('src/assembler.c')) do
26
+  for l in assert(io.lines('src/uxnasm.c')) do
27 27
     if l == 'char ops[][4] = {' then
28 28
       wanted = true
29 29
     elseif wanted then
... ...
@@ -34,7 +34,7 @@ opcodes_in_order = {}
34 34
 
35 35
 do -- opcodes
36 36
 	wanted = false
37
-	for l in assert io.lines 'src/assembler.c'
37
+	for l in assert io.lines 'src/uxnasm.c'
38 38
 		if l == 'char ops[][4] = {'
39 39
 			wanted = true
40 40
 		elseif wanted
... ...
@@ -219,7 +219,7 @@ for l in assert(io.lines('src/uxn.c')) do
219 219
 end
220 220
 i = 0
221 221
 wanted = false
222
-for l in assert(io.lines('src/assembler.c')) do
222
+for l in assert(io.lines('src/uxnasm.c')) do
223 223
   if l == 'char ops[][4] = {' then
224 224
     wanted = true
225 225
   elseif l == '};' then
... ...
@@ -156,7 +156,7 @@ for l in assert io.lines 'src/uxn.c'
156 156
 
157 157
 i = 0
158 158
 wanted = false
159
-for l in assert io.lines 'src/assembler.c'
159
+for l in assert io.lines 'src/uxnasm.c'
160 160
 	if l == 'char ops[][4] = {'
161 161
 		wanted = true
162 162
 	elseif l == '};'
... ...
@@ -1,6 +1,6 @@
1 1
 </$objtype/mkfile
2 2
 
3
-TARG=bin/debugger bin/uxnasm bin/uxnemu
3
+TARG=bin/uxncli bin/uxnasm bin/uxnemu
4 4
 USM=`{walk -f projects/ | grep '\.usm$' | grep -v blank.usm}
5 5
 ROM=${USM:%.usm=%.rom}
6 6
 CFLAGS=$CFLAGS -I/sys/include/npe
... ...
@@ -29,16 +29,16 @@ bin:
29 29
 %.rom:Q: %.usm bin/uxnasm
30 30
 	bin/uxnasm $stem.usm $target >/dev/null
31 31
 
32
-bin/debugger: debugger.$O uxn.$O
32
+bin/uxncli: uxncli.$O uxn.$O
33 33
 	$LD $LDFLAGS -o $target $prereq
34 34
 
35
-bin/uxnasm: assembler.$O
35
+bin/uxnasm: uxnasm.$O
36 36
 	$LD $LDFLAGS -o $target $prereq
37 37
 
38
-bin/uxnemu: emulator.$O apu.$O mpu.$O ppu.$O uxn.$O
38
+bin/uxnemu: uxnemu.$O apu.$O mpu.$O ppu.$O uxn.$O
39 39
 	$LD $LDFLAGS -o $target $prereq
40 40
 
41
-(assembler|debugger|emulator|uxn)\.$O:R: src/\1.c
41
+(uxnasm|uxncli|uxnemu|uxn)\.$O:R: src/\1.c
42 42
 	$CC $CFLAGS -Isrc -o $target src/$stem1.c
43 43
 
44 44
 (apu|mpu|ppu)\.$O:R: src/devices/\1.c
45 45
similarity index 100%
46 46
rename from projects/demos/automata.usm
47 47
rename to projects/examples/demos/automata.usm
48 48
similarity index 100%
49 49
rename from projects/demos/bifurcan.usm
50 50
rename to projects/examples/demos/bifurcan.usm
51 51
similarity index 100%
52 52
rename from projects/demos/darena.usm
53 53
rename to projects/examples/demos/darena.usm
54 54
similarity index 100%
55 55
rename from projects/demos/drum-rack.usm
56 56
rename to projects/examples/demos/drum-rack.usm
57 57
similarity index 100%
58 58
rename from projects/demos/life.usm
59 59
rename to projects/examples/demos/life.usm
60 60
similarity index 100%
61 61
rename from projects/demos/musictracker.usm
62 62
rename to projects/examples/demos/musictracker.usm
63 63
similarity index 100%
64 64
rename from projects/demos/neralie.usm
65 65
rename to projects/examples/demos/neralie.usm
66 66
similarity index 100%
67 67
rename from projects/demos/piano.usm
68 68
rename to projects/examples/demos/piano.usm
69 69
similarity index 100%
70 70
rename from projects/demos/polycat.usm
71 71
rename to projects/examples/demos/polycat.usm
72 72
similarity index 100%
73 73
rename from projects/demos/theme.usm
74 74
rename to projects/examples/demos/theme.usm
75 75
new file mode 100644
... ...
@@ -0,0 +1,143 @@
1
+( dev/audio )
2
+
3
+%4** { #20 SFT2 }
4
+%8** { #30 SFT2 }
5
+%MOD { DUP2 DIV MUL SUB }
6
+
7
+( devices )
8
+
9
+|00 @System     [ &vector $2 &pad      $6 &r      $2 &g     $2 &b      $2 ]
10
+|20 @Screen     [ &vector $2 &width    $2 &height $2 &pad   $2 &x      $2 &y    $2 &addr  $2 &color $1 ]
11
+|30 @Audio0     [ &vector $2 &position $2 &output $1 &pad   $3 &adsr   $2 &length $2 &addr  $2 &volume $1 &pitch $1 ]
12
+|40 @Audio1     [ &vector $2 &position $2 &output $1 &pad   $3 &adsr   $2 &length $2 &addr  $2 &volume $1 &pitch $1 ]
13
+|50 @Audio2     [ &vector $2 &position $2 &output $1 &pad   $3 &adsr   $2 &length $2 &addr  $2 &volume $1 &pitch $1 ]
14
+|60 @Audio3     [ &vector $2 &position $2 &output $1 &pad   $3 &adsr   $2 &length $2 &addr  $2 &volume $1 &pitch $1 ]
15
+
16
+( variables )
17
+
18
+|0000
19
+
20
+@timer    $1
21
+@counter  $1
22
+
23
+|0100 ( -> )
24
+	
25
+	( theme )
26
+	#00ff .System/r DEO2 
27
+	#0f0f .System/g DEO2 
28
+	#0ff0 .System/b DEO2 
29
+
30
+	( vectors )
31
+	;on-frame .Screen/vector DEO2
32
+
33
+	( setup synth )
34
+	#1202 .Audio0/adsr DEO2
35
+	;saw .Audio0/addr DEO2
36
+	#0100 .Audio0/length DEO2
37
+	#88 .Audio0/volume DEO
38
+
39
+	#0101 .Audio1/adsr DEO2
40
+	;tri .Audio1/addr DEO2
41
+	#0100 .Audio1/length DEO2
42
+	#88 .Audio1/volume DEO
43
+
44
+	#0112 .Audio2/adsr DEO2
45
+	;sin .Audio2/addr DEO2
46
+	#0100 .Audio2/length DEO2
47
+	#88 .Audio2/volume DEO
48
+
49
+	#0022 .Audio3/adsr DEO2
50
+	;piano .Audio3/addr DEO2
51
+	#0100 .Audio3/length DEO2
52
+	#88 .Audio3/volume DEO
53
+
54
+BRK
55
+
56
+@on-frame ( -> )
57
+
58
+	( incr ) .timer LDZ #01 ADD .timer STZ 
59
+	( skip ) .timer LDZ #10 EQU #01 JCN [ BRK ]
60
+
61
+	( get note )
62
+	.counter LDZ #18 MOD #30 ADD 
63
+		.Audio0/pitch .counter LDZ #04 MOD #10 MUL ADD DEO
64
+
65
+	.counter LDZ #01 ADD .counter STZ
66
+	#00 .timer STZ
67
+
68
+BRK
69
+
70
+@saw 
71
+	0003 0609 0c0f 1215 181b 1e21 2427 2a2d
72
+	3033 3639 3b3e 4143 4649 4b4e 5052 5557
73
+	595b 5e60 6264 6667 696b 6c6e 7071 7274
74
+	7576 7778 797a 7b7b 7c7d 7d7e 7e7e 7e7e
75
+	7f7e 7e7e 7e7e 7d7d 7c7b 7b7a 7978 7776
76
+	7574 7271 706e 6c6b 6967 6664 6260 5e5b
77
+	5957 5552 504e 4b49 4643 413e 3b39 3633
78
+	302d 2a27 2421 1e1b 1815 120f 0c09 0603
79
+	00fd faf7 f4f1 eeeb e8e5 e2df dcd9 d6d3
80
+	d0cd cac7 c5c2 bfbd bab7 b5b2 b0ae aba9
81
+	a7a5 a2a0 9e9c 9a99 9795 9492 908f 8e8c
82
+	8b8a 8988 8786 8585 8483 8382 8282 8282
83
+	8182 8282 8282 8383 8485 8586 8788 898a
84
+	8b8c 8e8f 9092 9495 9799 9a9c 9ea0 a2a5
85
+	a7a9 abae b0b2 b5b7 babd bfc2 c5c7 cacd
86
+	d0d3 d6d9 dcdf e2e5 e8eb eef1 f4f7 fafd 
87
+@tri
88
+	8082 8486 888a 8c8e 9092 9496 989a 9c9e
89
+	a0a2 a4a6 a8aa acae b0b2 b4b6 b8ba bcbe
90
+	c0c2 c4c6 c8ca ccce d0d2 d4d6 d8da dcde
91
+	e0e2 e4e6 e8ea ecee f0f2 f4f6 f8fa fcfe
92
+	fffd fbf9 f7f5 f3f1 efed ebe9 e7e5 e3e1
93
+	dfdd dbd9 d7d5 d3d1 cfcd cbc9 c7c5 c3c1
94
+	bfbd bbb9 b7b5 b3b1 afad aba9 a7a5 a3a1
95
+	9f9d 9b99 9795 9391 8f8d 8b89 8785 8381
96
+	7f7d 7b79 7775 7371 6f6d 6b69 6765 6361
97
+	5f5d 5b59 5755 5351 4f4d 4b49 4745 4341
98
+	3f3d 3b39 3735 3331 2f2d 2b29 2725 2321
99
+	1f1d 1b19 1715 1311 0f0d 0b09 0705 0301
100
+	0103 0507 090b 0d0f 1113 1517 191b 1d1f
101
+	2123 2527 292b 2d2f 3133 3537 393b 3d3f
102
+	4143 4547 494b 4d4f 5153 5557 595b 5d5f
103
+	6163 6567 696b 6d6f 7173 7577 797b 7d7f
104
+@sin
105
+	8083 8689 8c8f 9295 989b 9ea1 a4a7 aaad
106
+	b0b3 b6b9 bbbe c1c3 c6c9 cbce d0d2 d5d7
107
+	d9db dee0 e2e4 e6e7 e9eb ecee f0f1 f2f4
108
+	f5f6 f7f8 f9fa fbfb fcfd fdfe fefe fefe
109
+	fffe fefe fefe fdfd fcfb fbfa f9f8 f7f6
110
+	f5f4 f2f1 f0ee eceb e9e7 e6e4 e2e0 dedb
111
+	d9d7 d5d2 d0ce cbc9 c6c3 c1be bbb9 b6b3
112
+	b0ad aaa7 a4a1 9e9b 9895 928f 8c89 8683
113
+	807d 7a77 7471 6e6b 6865 625f 5c59 5653
114
+	504d 4a47 4542 3f3d 3a37 3532 302e 2b29
115
+	2725 2220 1e1c 1a19 1715 1412 100f 0e0c
116
+	0b0a 0908 0706 0505 0403 0302 0202 0202
117
+	0102 0202 0202 0303 0405 0506 0708 090a
118
+	0b0c 0e0f 1012 1415 1719 1a1c 1e20 2225
119
+	2729 2b2e 3032 3537 3a3d 3f42 4547 4a4d
120
+	5053 5659 5c5f 6265 686b 6e71 7477 7a7d
121
+@piano
122
+	8182 8588 8d91 959b a1a6 aaad b2b5 b8bd
123
+	c1c7 cbd0 d5d9 dde1 e5e5 e4e4 e1dc d7d1
124
+	cbc5 bfb8 b2ac a6a2 9c97 928d 8884 807c
125
+	7977 7574 7372 7272 7273 7372 706d 6964
126
+	605b 5650 4d49 4643 4342 4244 4548 4a4d
127
+	5052 5556 5758 5554 5150 4c4a 4744 423f
128
+	3d3c 3a38 3835 3431 3030 2f31 3336 393e
129
+	4449 4e54 5a60 666b 7175 7b82 8990 989e
130
+	a6ab b1b6 babd bebf bfbe bbb9 b6b3 b0ae
131
+	aaa8 a6a3 a19e 9c9a 9997 9696 9798 9b9e
132
+	a1a4 a6a9 a9ac adad adae aeaf b0b0 b1b1
133
+	b3b3 b4b4 b4b3 b3b1 b0ad abab a9a9 a8a8
134
+	a7a5 a19d 9891 8b84 7e77 726e 6b6b 6b6c
135
+	6f71 7477 7776 7370 6c65 5e56 4e48 423f
136
+	3d3c 3b3a 3a39 3838 3839 393a 3c3e 4146
137
+	4a50 575b 6064 686a 6e70 7274 7677 7a7d
138
+
139
+@melody [ 
140
+	54 52 54 4f 4b 4f 48 ff
141
+	54 52 54 4f 4b 4f 48 ff
142
+	54 56 57 56 57 54 56 54 
143
+	56 52 54 52 54 50 54 ff ] 
... ...
@@ -9,7 +9,7 @@
9 9
 	Asma - an in-Uxn assembler
10 10
 
11 11
 	This assembler aims to be binary compatible with the output from
12
-	src/assembler.c, but unlike that assembler this one can be run inside Uxn
12
+	src/uxnasm.c, but unlike that assembler this one can be run inside Uxn
13 13
 	itself!
14 14
 
15 15
 	Asma is designed to be able to be copy-pasted inside another project, so
... ...
@@ -107,7 +107,7 @@ putchr(Ppu *p, Layer *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uin
107 107
 /* output */
108 108
 
109 109
 void
110
-drawdebugger(Ppu *p, Uint8 *stack, Uint8 ptr)
110
+inspect(Ppu *p, Uint8 *stack, Uint8 ptr)
111 111
 {
112 112
 	Uint8 i, x, y, b;
113 113
 	for(i = 0; i < 0x20; ++i) { /* memory */
... ...
@@ -31,4 +31,4 @@ void putcolors(Ppu *p, Uint8 *addr);
31 31
 void putpixel(Ppu *p, Layer *layer, Uint16 x, Uint16 y, Uint8 color);
32 32
 void puticn(Ppu *p, Layer *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy);
33 33
 void putchr(Ppu *p, Layer *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy);
34
-void drawdebugger(Ppu *p, Uint8 *stack, Uint8 ptr);
34
+void inspect(Ppu *p, Uint8 *stack, Uint8 ptr);
35 35
similarity index 99%
36 36
rename from src/assembler.c
37 37
rename to src/uxnasm.c
... ...
@@ -296,9 +296,9 @@ pass1(FILE *f)
296 296
 	printf("Pass 1\n");
297 297
 	while(fscanf(f, "%s", w) == 1) {
298 298
 		if(skipblock(w, &ccmnt, '(', ')')) continue;
299
-		if(w[0] == '|') {
299
+		if(w[0] == '|')
300 300
 			addr = shex(w + 1);
301
-		} else if(w[0] == '%') {
301
+		else if(w[0] == '%') {
302 302
 			if(!makemacro(w + 1, f))
303 303
 				return error("Pass1 failed", w);
304 304
 		} else if(w[0] == '@') {
305 305
similarity index 58%
306 306
rename from src/debugger.c
307 307
rename to src/uxncli.c
... ...
@@ -1,4 +1,5 @@
1 1
 #include <stdio.h>
2
+#include <time.h>
2 3
 #include "uxn.h"
3 4
 
4 5
 /*
... ...
@@ -25,6 +26,7 @@ void
25 26
 printstack(Stack *s)
26 27
 {
27 28
 	Uint8 x, y;
29
+	printf("\n\n");
28 30
 	for(y = 0; y < 0x08; ++y) {
29 31
 		for(x = 0; x < 0x08; ++x) {
30 32
 			Uint8 p = y * 0x08 + x;
... ...
@@ -60,14 +62,35 @@ file_talk(Device *d, Uint8 b0, Uint8 w)
60 62
 		Uint16 addr = mempeek16(d->dat, b0 - 1);
61 63
 		FILE *f = fopen(name, read ? "r" : (offset ? "a" : "w"));
62 64
 		if(f) {
63
-			if(fseek(f, offset, SEEK_SET) != -1 && (result = read ? fread(&d->mem[addr], 1, length, f) : fwrite(&d->mem[addr], 1, length, f)))
64
-				printf("%s %d bytes, at %04x from %s\n", read ? "Loaded" : "Saved", result, addr, name);
65
+			printf("%s %04x %s %s: ", read ? "Loading" : "Saving", addr, read ? "from" : "to", name);
66
+			if(fseek(f, offset, SEEK_SET) != -1)
67
+				result = read ? fread(&d->mem[addr], 1, length, f) : fwrite(&d->mem[addr], 1, length, f);
68
+			printf("%04x bytes\n", result);
65 69
 			fclose(f);
66 70
 		}
67 71
 		mempoke16(d->dat, 0x2, result);
68 72
 	}
69 73
 }
70 74
 
75
+void
76
+datetime_talk(Device *d, Uint8 b0, Uint8 w)
77
+{
78
+	time_t seconds = time(NULL);
79
+	struct tm *t = localtime(&seconds);
80
+	t->tm_year += 1900;
81
+	mempoke16(d->dat, 0x0, t->tm_year);
82
+	d->dat[0x2] = t->tm_mon;
83
+	d->dat[0x3] = t->tm_mday;
84
+	d->dat[0x4] = t->tm_hour;
85
+	d->dat[0x5] = t->tm_min;
86
+	d->dat[0x6] = t->tm_sec;
87
+	d->dat[0x7] = t->tm_wday;
88
+	mempoke16(d->dat, 0x08, t->tm_yday);
89
+	d->dat[0xa] = t->tm_isdst;
90
+	(void)b0;
91
+	(void)w;
92
+}
93
+
71 94
 void
72 95
 nil_talk(Device *d, Uint8 b0, Uint8 w)
73 96
 {
... ...
@@ -81,10 +104,8 @@ nil_talk(Device *d, Uint8 b0, Uint8 w)
81 104
 int
82 105
 start(Uxn *u)
83 106
 {
84
-	printf("RESET --------\n");
85 107
 	if(!evaluxn(u, PAGE_PROGRAM))
86 108
 		return error("Reset", "Failed");
87
-	printstack(&u->wst);
88 109
 	return 1;
89 110
 }
90 111
 
... ...
@@ -100,23 +121,26 @@ main(int argc, char **argv)
100 121
 	if(!loaduxn(&u, argv[1]))
101 122
 		return error("Load", "Failed");
102 123
 
103
-	portuxn(&u, 0x00, "empty", nil_talk);
104
-	portuxn(&u, 0x01, "console", console_talk);
105
-	portuxn(&u, 0x02, "empty", nil_talk);
106
-	portuxn(&u, 0x03, "empty", nil_talk);
107
-	portuxn(&u, 0x04, "empty", nil_talk);
108
-	portuxn(&u, 0x05, "empty", nil_talk);
109
-	portuxn(&u, 0x06, "empty", nil_talk);
110
-	portuxn(&u, 0x07, "empty", nil_talk);
111
-	portuxn(&u, 0x08, "empty", nil_talk);
112
-	portuxn(&u, 0x09, "empty", nil_talk);
113
-	portuxn(&u, 0x0a, "file", file_talk);
114
-	portuxn(&u, 0x0b, "empty", nil_talk);
115
-	portuxn(&u, 0x0c, "empty", nil_talk);
116
-	portuxn(&u, 0x0d, "empty", nil_talk);
117
-	portuxn(&u, 0x0e, "empty", nil_talk);
118
-	portuxn(&u, 0x0f, "empty", nil_talk);
124
+	portuxn(&u, 0x0, "empty", nil_talk);
125
+	portuxn(&u, 0x1, "console", console_talk);
126
+	portuxn(&u, 0x2, "empty", nil_talk);
127
+	portuxn(&u, 0x3, "empty", nil_talk);
128
+	portuxn(&u, 0x4, "empty", nil_talk);
129
+	portuxn(&u, 0x5, "empty", nil_talk);
130
+	portuxn(&u, 0x6, "empty", nil_talk);
131
+	portuxn(&u, 0x7, "empty", nil_talk);
132
+	portuxn(&u, 0x8, "empty", nil_talk);
133
+	portuxn(&u, 0x9, "empty", nil_talk);
134
+	portuxn(&u, 0xa, "file", file_talk);
135
+	portuxn(&u, 0xb, "datetime", datetime_talk);
136
+	portuxn(&u, 0xc, "empty", nil_talk);
137
+	portuxn(&u, 0xd, "empty", nil_talk);
138
+	portuxn(&u, 0xe, "empty", nil_talk);
139
+	portuxn(&u, 0xf, "empty", nil_talk);
140
+	
119 141
 	start(&u);
120 142
 
143
+	if(argc > 2)
144
+		printstack(&u.wst);
121 145
 	return 0;
122 146
 }
123 147
similarity index 99%
124 148
rename from src/emulator.c
125 149
rename to src/uxnemu.c
... ...
@@ -59,7 +59,7 @@ void
59 59
 redraw(Uxn *u)
60 60
 {
61 61
 	if(debug)
62
-		drawdebugger(&ppu, u->wst.dat, u->wst.ptr);
62
+		inspect(&ppu, u->wst.dat, u->wst.ptr);
63 63
 	SDL_UpdateTexture(bgTexture, &gRect, ppu.bg.pixels, ppu.width * sizeof(Uint32));
64 64
 	SDL_UpdateTexture(fgTexture, &gRect, ppu.fg.pixels, ppu.width * sizeof(Uint32));
65 65
 	SDL_RenderClear(gRenderer);
... ...
@@ -245,7 +245,6 @@ screen_talk(Device *d, Uint8 b0, Uint8 w)
245 245
 			puticn(&ppu, layer, x, y, addr, d->dat[0xe] & 0xf, mode & 0x2, mode & 0x4);
246 246
 		else
247 247
 			putchr(&ppu, layer, x, y, addr, d->dat[0xe] & 0xf, mode & 0x2, mode & 0x4);
248
-
249 248
 		reqdraw = 1;
250 249
 	}
251 250
 }