Browse code

File device: drop offset shorts, add stat and delete.

Andrew Alderwick authored on 05/11/2021 21:32:45
Showing 20 changed files
... ...
@@ -17,6 +17,8 @@ then
17 17
 	clang-format -i src/devices/ppu.c
18 18
 	clang-format -i src/devices/apu.h
19 19
 	clang-format -i src/devices/apu.c
20
+	clang-format -i src/devices/file.h
21
+	clang-format -i src/devices/file.c
20 22
 	clang-format -i src/uxnasm.c
21 23
 	clang-format -i src/uxnemu.c
22 24
 	clang-format -i src/uxncli.c
... ...
@@ -49,8 +51,8 @@ fi
49 51
 
50 52
 echo "Building.."
51 53
 cc ${CFLAGS} src/uxnasm.c -o bin/uxnasm
52
-cc ${CFLAGS} ${CORE} src/devices/ppu.c src/devices/apu.c src/uxnemu.c ${UXNEMU_LDFLAGS} -o bin/uxnemu
53
-cc ${CFLAGS} ${CORE} src/uxncli.c -o bin/uxncli
54
+cc ${CFLAGS} ${CORE} src/devices/file.c src/devices/ppu.c src/devices/apu.c src/uxnemu.c ${UXNEMU_LDFLAGS} -o bin/uxnemu
55
+cc ${CFLAGS} ${CORE} src/devices/file.c src/uxncli.c -o bin/uxncli
54 56
 
55 57
 if [ -d "$HOME/bin" ]
56 58
 then
... ...
@@ -21,7 +21,7 @@
21 21
 |60 @Audio3     [ &vector $2 &position $2 &output $1 &pad   $3 &adsr   $2 &length $2 &addr $2 &volume $1 &pitch $1 ]
22 22
 |80 @Controller [ &vector $2 &button   $1 &key    $1 ]
23 23
 |90 @Mouse      [ &vector $2 &x        $2 &y      $2 &state $1 &wheel  $1 ]
24
-|a0 @File       [ &vector $2 &success  $2 &offset-hs $2 &offset-ls $2 &name   $2 &length $2 &load $2 &save   $2 ]
24
+|a0 @File       [ &vector $2 &name     $2 &length $2 &success $2 &load $2 &save   $2 &stat $2 &delete $1 ]
25 25
 |b0 @DateTime   [ &year   $2 &month    $1 &day    $1 &hour  $1 &minute $1 &second $1 &dotw $1 &doty   $2 &isdst $1 ]
26 26
 
27 27
 ( variables )
... ...
@@ -2,7 +2,7 @@
2 2
 
3 3
 |00 @System     [ &vector $2 &wst      $1 &rst    $1 &pad   $4 &r $2 &g $2 &b $2   &debug $1 &halt $1 ]
4 4
 |10 @Console    [ &vector $2 &read     $1 &pad    $5 &write $1 &error  $1 ]
5
-|a0 @File       [ &vector $2 &success  $2 &offset-hs $2 &offset-ls $2 &name $2 &length $2 &load $2 &save $2 ]
5
+|a0 @File       [ &vector $2 &name     $2 &length $2 &success $2 &load $2 &save $2 &stat $2 &delete $1 ]
6 6
 
7 7
 ( vectors )
8 8
 
... ...
@@ -51,7 +51,6 @@
51 51
 		that will prevent an infinite loop.
52 52
 	)
53 53
 	;&dest-file .File/name DEO2
54
-	#0000 .File/offset-ls DEO2
55 54
 	#ff00 .File/length DEO2
56 55
 	#0100 .File/load
57 56
 	LIT DEO2 #00ff STA
... ...
@@ -30,7 +30,7 @@
30 30
 |70 @Midi       [ &vector $2 &channel  $1 &note   $1 &velocity $1 ]
31 31
 |80 @Controller [ &vector $2 &button   $1 &key    $1 ]
32 32
 |90 @Mouse      [ &vector $2 &x        $2 &y      $2 &state $1 &wheel $1 ]
33
-|a0 @File       [ &vector $2 &success  $2 &offset-hs $2 &offset-ls $2 &name $2 &length $2 &load $2 &save $2 ]
33
+|a0 @File       [ &vector $2 &name     $2 &length $2 &success $2 &load $2 &save $2 &stat $2 &delete $1 ]
34 34
 
35 35
 ( variables )
36 36
 
... ...
@@ -12,7 +12,7 @@
12 12
 
13 13
 |00 @System  &vector $2 &pad     $6 &r      $2 &g     $2 &b      $2
14 14
 |20 @Screen  &vector $2 &width   $2 &height $2 &pad   $2 &x      $2 &y      $2 &addr $2 &pixel $1 &sprite $1
15
-|a0 @File    &vector $2 &success $2 &offset-hs $2 &offset-ls $2 &name $2 &length $2 &load $2 &save $2
15
+|a0 @File    &vector $2 &name    $2 &length $2 &success $2 &load $2 &save   $2 &stat $2 &delete $1
16 16
 
17 17
 ( variables )
18 18
 
... ...
@@ -27,7 +27,7 @@
27 27
 |70 @Midi       [ &vector $2 &channel  $1 &note   $1 &velocity $1 ]
28 28
 |80 @Controller [ &vector $2 &button   $1 &key    $1 ]
29 29
 |90 @Mouse      [ &vector $2 &x        $2 &y      $2 &state $1 &wheel  $1 ]
30
-|a0 @File       [ &vector $2 &success  $2 &offset-hs $2 &offset-ls $2 &name $2 &length $2 &load $2 &save $2 ]
30
+|a0 @File       [ &vector $2 &name     $2 &length $2 &success $2 &load $2 &save $2 &stat $2 &delete $1 ]
31 31
 
32 32
 ( variables )
33 33
 
... ...
@@ -4,7 +4,7 @@
4 4
 
5 5
 |00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ]
6 6
 |20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
7
-|a0 @File   [ &vector $2 &success $2 &offset-hs $2 &offset-ls $2 &name $2 &length $2 &load $2 &save $2 ]
7
+|a0 @File   [ &vector $2 &name $2 &length $2 &success $2 &load $2 &save $2 &stat $2 &delete $1 ]
8 8
 
9 9
 ( variables )
10 10
 
... ...
@@ -3,7 +3,7 @@
3 3
 ( devices )
4 4
 
5 5
 |00 @System     [ &vector $2 &pad    $6 &r      $2 &g     $2 &b      $2 ]
6
-|a0 @File       [ &vector $2 &success $2 &offset-hs $2 &offset-ls $2 &name $2 &length $2 &load $2 &save $2 ]
6
+|a0 @File       [ &vector $2 &name $2 &length $2 &success $2 &load $2 &save $2 &stat $2 &delete $1 ]
7 7
 
8 8
 ( variables )
9 9
 
... ...
@@ -8,7 +8,7 @@
8 8
 |00 @System     [ &vector $2 &pad    $6 &r      $2 &g     $2 &b      $2 ]
9 9
 |10 @Console    [ &pad    $8 &write  $1 ]
10 10
 |20 @Screen     [ &vector $2 &width  $2 &height $2 &pad   $2 &x      $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
11
-|a0 @File       [ &vector $2 &success $2 &offset-hs $2 &offset-ls $2 &name $2 &length $2 &load $2 &save $2 ]
11
+|a0 @File       [ &vector $2 &name $2 &length $2 &success $2 &load $2 &save $2 &stat $2 &delete $1 ]
12 12
 
13 13
 ( variables )
14 14
 
... ...
@@ -7,7 +7,7 @@
7 7
 
8 8
 |00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ]
9 9
 |20 @Screen [ &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
10
-|a0 @File [ &vector $2 &success $2 &offset-hs $2 &offset-ls $2 &name $2 &length $2 &load $2 &save $2 ]
10
+|a0 @File [ &vector $2 &name $2 &length $2 &success $2 &load $2 &save $2 &stat $2 &delete $1 ]
11 11
 
12 12
 ( variables )
13 13
 
... ...
@@ -196,12 +196,11 @@
196 196
 @asma-init-next-pass ( -- )
197 197
 	;asma/pass LDA INC ;asma/pass STA
198 198
 	;asma-write-buffer ;asma-output/ptr STA2
199
-	#0000 DUP2k
200
-		;asma-output/offset STA2
199
+	#0000 DUP2
201 200
 		;asma/addr STA2
202 201
 		;asma/state STA
203 202
 	#01 SWP ( 0100 ) ;asma/written-addr STA2
204
-	;&preamble-end ;&preamble SUB2k ,asma-assemble-chunk JSR POP2 POP2
203
+	;&preamble-end ;&preamble SUB2k ;asma-assemble-chunk JSR2 POP2 POP2
205 204
 	JMP2r
206 205
 
207 206
 	&preamble
... ...
@@ -498,15 +497,14 @@ include projects/library/binary-tree.tal
498 497
 	NIP2 ( start* )
499 498
 	,&after-flush JMP
500 499
 
501
-@asma-output [ &ptr $2 &offset $2 ]
500
+@asma-output [ &ptr $2 ]
502 501
 
503 502
 @asma-flush-ignore ( len* -- )
504 503
 	POP2
505 504
 	JMP2r
506 505
 
507 506
 @asma-flush-to-file ( len* -- )
508
-	DUP2 .File/length DEO2
509
-	,asma-output/offset LDR2 DUP2 .File/offset-ls DEO2 ADD2 ,asma-output/offset STR2
507
+	.File/length DEO2
510 508
 	;asma/dest-filename LDA2 .File/name DEO2
511 509
 	;asma-write-buffer .File/save DEO2
512 510
 	JMP2r
... ...
@@ -2,6 +2,14 @@
2 2
 
3 3
 # Summary
4 4
 
5
+*** CAUTION: this library is deprecated! ***
6
+
7
+Chunked file reads are now possible in the File device directly: just use
8
+File/load or File/save multiple times. This library exists for compatibility to
9
+keep asma going until it gets a more substantial rewrite.
10
+
11
+***
12
+
5 13
 Reads a file in chunks - perfect for when you have a small buffer or when you
6 14
 don't know the file size. Copes with files up to 4,294,967,295 bytes long.
7 15
 
... ...
@@ -17,9 +25,11 @@ don't know the file size. Copes with files up to 4,294,967,295 bytes long.
17 25
 
18 26
 	&loop
19 27
 	STH2kr .File/name DEO2     ( F* U* B* OL* OH* SZ*     / FN* )
20
-	STH2k .File/length DEO2    ( F* U* B* OL* OH*         / FN* SZ* )
21
-	STH2k .File/offset-hs DEO2 ( F* U* B* OL*             / FN* SZ* OH* )
22
-	STH2k .File/offset-ls DEO2 ( F* U* B*                 / FN* SZ* OH* OL* )
28
+	STH2k ,ffwd/length STR2    ( F* U* B* OL* OH*         / FN* SZ* )
29
+	STH2                       ( F* U* B* OL*             / FN* SZ* OH* )
30
+	STH2k ,ffwd/offset STR2    ( F* U* B*                 / FN* SZ* OH* OL* )
31
+	DUP2 ,ffwd/addr STR2
32
+	,ffwd JSR
23 33
 	SWP2                       ( F* B* U*                 / FN* SZ* OH* OL* )
24 34
 	ROT2k NIP2                 ( F* B* U* B* F*           / FN* SZ* OH* OL* )
25 35
 	OVR2 .File/load DEO2       ( F* B* U* B* F*           / FN* SZ* OH* OL* )
... ...
@@ -40,6 +50,25 @@ don't know the file size. Copes with files up to 4,294,967,295 bytes long.
40 50
 	STH2r STH2r                ( F* U'* B* OL'* OH'* SZ*     / FN* )
41 51
 	,&loop JMP
42 52
 
53
+@ffwd
54
+	LIT2 &length $2
55
+	LIT2 &offset $2
56
+
57
+	&coarse ( length* offset* )
58
+	GTH2k ,&fine JCN
59
+	OVR2 .File/length DEO2
60
+	,&addr LDR2 .File/load DEO2
61
+	OVR2 SUB2
62
+	,&coarse JMP
63
+
64
+	&fine ( length* offset* )
65
+	.File/length DEO2 ( length* )
66
+	,&addr LDR2 .File/load DEO2
67
+	.File/length DEO2 ( )
68
+	JMP2r
69
+
70
+	&addr $2
71
+
43 72
 (
44 73
 
45 74
 # Arguments
... ...
@@ -11,8 +11,6 @@
11 11
 )
12 12
 
13 13
 	.File/name DEO2
14
-	#0000 .File/offset-hs DEO2
15
-	#0000 .File/offset-ls DEO2
16 14
 
17 15
 	( return if file can't be found, or zero length )
18 16
 	#0001 .File/length DEO2
... ...
@@ -1,8 +1,8 @@
1 1
 ( devices )
2 2
 
3
-|00 @System     [ &vector $2 &wst      $1 &rst    $1 &pad   $4 &r $2 &g $2 &b $2   &debug $1 &halt $1 ]
4
-|10 @Console    [ &vector $2 &read     $1 &pad    $5 &write $1 &error  $1 ]
5
-|a0 @File       [ &vector $2 &success  $2 &offset-hs $2 &offset-ls $2 &name $2 &length $2 &load $2 &save $2 ]
3
+|00 @System     [ &vector $2 &wst  $1 &rst    $1 &pad   $4 &r $2 &g $2 &b $2   &debug $1 &halt $1 ]
4
+|10 @Console    [ &vector $2 &read $1 &pad    $5 &write $1 &error  $1 ]
5
+|a0 @File       [ &vector $2 &name $2 &length $2 &success $2 &load $2 &save $2 &stat $2 &delete $1 ]
6 6
 
7 7
 ( vectors )
8 8
 
... ...
@@ -35,7 +35,7 @@
35 35
 |30 @Audio0     [ &vector $2 &position $2 &output $1 &pad   $3 &adsr   $2 &length $2 &addr $2 &volume $1 &pitch $1 ]
36 36
 |80 @Controller [ &vector $2 &button   $1 &key    $1 ]
37 37
 |90 @Mouse      [ &vector $2 &x        $2 &y      $2 &state $1 &wheel  $1 ]
38
-|a0 @File       [ &vector $2 &success  $2 &offset-hs $2 &offset-ls $2 &name   $2 &length $2 &load $2 &save   $2 ]
38
+|a0 @File       [ &vector $2 &name     $2 &length $2 &success $2 &load $2 &save $2 &stat $2 &delete $1 ]
39 39
 
40 40
 ( variables )
41 41
 
... ...
@@ -22,7 +22,7 @@
22 22
 |20 @Screen  &vector $2 &width   $2 &height $2 &auto $1 &pad $1 &x      $2 &y      $2 &addr $2 &pixel $1 &sprite $1
23 23
 |80 @Controller [ &vector $2 &button $1 &key    $1 ]
24 24
 |90 @Mouse      [ &vector $2 &x        $2 &y      $2 &state $1 &wheel  $1 ]
25
-|a0 @File    &vector $2 &success $2 &offset-hs $2 &offset-ls $2 &name $2 &length $2 &load $2 &save $2
25
+|a0 @File    &vector $2 &name $2 &length $2 &success $2 &load $2 &save $2 &stat $2 &delete $1
26 26
 |b0 @DateTime   [ &year   $2 &month    $1 &day    $1 &hour  $1 &minute $1 &second $1 &dotw $1 &doty $2 &isdst $1 ]
27 27
 
28 28
 ( variables )
29 29
new file mode 100644
... ...
@@ -0,0 +1,135 @@
1
+#include "../uxn.h"
2
+#include "file.h"
3
+
4
+/*
5
+Copyright (c) 2021 Devine Lu Linvega
6
+Copyright (c) 2021 Andrew Alderwick
7
+
8
+Permission to use, copy, modify, and distribute this software for any
9
+purpose with or without fee is hereby granted, provided that the above
10
+copyright notice and this permission notice appear in all copies.
11
+
12
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13
+WITH REGARD TO THIS SOFTWARE.
14
+*/
15
+
16
+#define _POSIX_C_SOURCE 200809L
17
+
18
+#include <stdio.h>
19
+#include <dirent.h>
20
+#include <string.h>
21
+#include <sys/stat.h>
22
+#include <unistd.h>
23
+
24
+static FILE *f;
25
+static DIR *d;
26
+static int dir_fd;
27
+static char *current_filename;
28
+static enum { IDLE,
29
+	FILE_READ,
30
+	FILE_WRITE,
31
+	DIR_READ } state;
32
+static struct dirent *de;
33
+
34
+static char hex[] = "0123456789abcdef";
35
+
36
+static void
37
+reset(void)
38
+{
39
+	if(f != NULL) {
40
+		fclose(f);
41
+		f = NULL;
42
+	}
43
+	if(d != NULL) {
44
+		closedir(d);
45
+		d = NULL;
46
+	}
47
+	de = NULL;
48
+	state = IDLE;
49
+}
50
+
51
+void
52
+file_prepare(void *filename)
53
+{
54
+	reset();
55
+	current_filename = (char *)filename;
56
+}
57
+
58
+static Uint16
59
+write_entry(char *p, Uint16 len, const char *filename, struct stat *st)
60
+{
61
+	if(len < strlen(filename) + 7) return 0;
62
+	memcpy(p, "???? ", 5);
63
+	strcpy(p + 5, filename);
64
+	strcat(p, "\n");
65
+	if(S_ISDIR(st->st_mode)) {
66
+		memcpy(p, "---- ", 5);
67
+	} else if(st->st_size < 0x10000) {
68
+		p[0] = hex[(st->st_size >> 12) & 0xf];
69
+		p[1] = hex[(st->st_size >> 8) & 0xf];
70
+		p[2] = hex[(st->st_size >> 4) & 0xf];
71
+		p[3] = hex[(st->st_size >> 0) & 0xf];
72
+	}
73
+	return strlen(p);
74
+}
75
+
76
+Uint16
77
+file_read(void *dest, Uint16 len)
78
+{
79
+	if(state != FILE_READ && state != DIR_READ) {
80
+		reset();
81
+		if((d = opendir(current_filename)) != NULL) {
82
+			state = DIR_READ;
83
+			dir_fd = dirfd(d);
84
+		} else if((f = fopen(current_filename, "rb")) != NULL)
85
+			state = FILE_READ;
86
+	}
87
+	if(state == FILE_READ)
88
+		return fread(dest, 1, len, f);
89
+	if(state == DIR_READ) {
90
+		char *p = dest;
91
+		if(de == NULL) de = readdir(d);
92
+		for(; de != NULL; de = readdir(d)) {
93
+			struct stat st;
94
+			Uint16 n;
95
+			if(de->d_name[0] == '.' && de->d_name[1] == '\0')
96
+				continue;
97
+			if(fstatat(dir_fd, de->d_name, &st, 0))
98
+				continue;
99
+			n = write_entry(p, len, de->d_name, &st);
100
+			if(!n) break;
101
+			p += n;
102
+			len -= n;
103
+		}
104
+		return p - (char *)dest;
105
+	}
106
+	return 0;
107
+}
108
+
109
+Uint16
110
+file_write(void *src, Uint16 len)
111
+{
112
+	if(state != FILE_WRITE) {
113
+		reset();
114
+		if((f = fopen(current_filename, "ab")) != NULL)
115
+			state = FILE_WRITE;
116
+	}
117
+	if(state == FILE_WRITE)
118
+		return fwrite(src, 1, len, f);
119
+	return 0;
120
+}
121
+
122
+Uint16
123
+file_stat(void *dest, Uint16 len)
124
+{
125
+	struct stat st;
126
+	if(stat(current_filename, &st))
127
+		return 0;
128
+	return write_entry((char *)dest, len, current_filename, &st);
129
+}
130
+
131
+Uint16
132
+file_delete(void)
133
+{
134
+	return unlink(current_filename);
135
+}
0 136
new file mode 100644
... ...
@@ -0,0 +1,17 @@
1
+/*
2
+Copyright (c) 2021 Devine Lu Linvega
3
+Copyright (c) 2021 Andrew Alderwick
4
+
5
+Permission to use, copy, modify, and distribute this software for any
6
+purpose with or without fee is hereby granted, provided that the above
7
+copyright notice and this permission notice appear in all copies.
8
+
9
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+WITH REGARD TO THIS SOFTWARE.
11
+*/
12
+
13
+void file_prepare(void *filename);
14
+Uint16 file_read(void *dest, Uint16 len);
15
+Uint16 file_write(void *src, Uint16 len);
16
+Uint16 file_stat(void *dest, Uint16 len);
17
+Uint16 file_delete();
... ...
@@ -2,6 +2,7 @@
2 2
 #include <unistd.h>
3 3
 #include <time.h>
4 4
 #include "uxn.h"
5
+#include "devices/file.h"
5 6
 
6 7
 /*
7 8
 Copyright (c) 2021 Devine Lu Linvega
... ...
@@ -78,19 +79,22 @@ console_deo(Device *d, Uint8 port)
78 79
 static void
79 80
 file_deo(Device *d, Uint8 port)
80 81
 {
81
-	Uint8 read = port == 0xd;
82
-	if(read || port == 0xf) {
83
-		char *name = (char *)&d->mem[peek16(d->dat, 0x8)];
84
-		Uint16 result = 0, length = peek16(d->dat, 0xa);
85
-		long offset = (peek16(d->dat, 0x4) << 16) + peek16(d->dat, 0x6);
86
-		Uint16 addr = peek16(d->dat, port - 1);
87
-		FILE *f = fopen(name, read ? "rb" : (offset ? "ab" : "wb"));
88
-		if(f) {
89
-			if(fseek(f, offset, SEEK_SET) != -1)
90
-				result = read ? fread(&d->mem[addr], 1, length, f) : fwrite(&d->mem[addr], 1, length, f);
91
-			fclose(f);
92
-		}
93
-		poke16(d->dat, 0x2, result);
82
+	switch(port) {
83
+	case 0x3:
84
+		file_prepare(&d->mem[peek16(d->dat, 0x2)]);
85
+		break;
86
+	case 0x9:
87
+		poke16(d->dat, 0x6, file_read(&d->mem[peek16(d->dat, 0x8)], peek16(d->dat, 0x4)));
88
+		break;
89
+	case 0xb:
90
+		poke16(d->dat, 0x6, file_write(&d->mem[peek16(d->dat, 0xa)], peek16(d->dat, 0x4)));
91
+		break;
92
+	case 0xd:
93
+		poke16(d->dat, 0x6, file_stat(&d->mem[peek16(d->dat, 0xc)], peek16(d->dat, 0x4)));
94
+		break;
95
+	case 0xe:
96
+		poke16(d->dat, 0x6, file_delete());
97
+		break;
94 98
 	}
95 99
 }
96 100
 
... ...
@@ -8,6 +8,7 @@
8 8
 #include <SDL.h>
9 9
 #include "devices/ppu.h"
10 10
 #include "devices/apu.h"
11
+#include "devices/file.h"
11 12
 #pragma GCC diagnostic pop
12 13
 
13 14
 /*
... ...
@@ -370,19 +371,22 @@ screen_deo(Device *d, Uint8 port)
370 371
 static void
371 372
 file_deo(Device *d, Uint8 port)
372 373
 {
373
-	Uint8 read = port == 0xd;
374
-	if(read || port == 0xf) {
375
-		char *name = (char *)&d->mem[peek16(d->dat, 0x8)];
376
-		Uint16 result = 0, length = peek16(d->dat, 0xa);
377
-		long offset = (peek16(d->dat, 0x4) << 16) + peek16(d->dat, 0x6);
378
-		Uint16 addr = peek16(d->dat, port - 1);
379
-		FILE *f = fopen(name, read ? "rb" : (offset ? "ab" : "wb"));
380
-		if(f) {
381
-			if(fseek(f, offset, SEEK_SET) != -1)
382
-				result = read ? fread(&d->mem[addr], 1, length, f) : fwrite(&d->mem[addr], 1, length, f);
383
-			fclose(f);
384
-		}
385
-		poke16(d->dat, 0x2, result);
374
+	switch(port) {
375
+	case 0x3:
376
+		file_prepare(&d->mem[peek16(d->dat, 0x2)]);
377
+		break;
378
+	case 0x9:
379
+		poke16(d->dat, 0x6, file_read(&d->mem[peek16(d->dat, 0x8)], peek16(d->dat, 0x4)));
380
+		break;
381
+	case 0xb:
382
+		poke16(d->dat, 0x6, file_write(&d->mem[peek16(d->dat, 0xa)], peek16(d->dat, 0x4)));
383
+		break;
384
+	case 0xd:
385
+		poke16(d->dat, 0x6, file_stat(&d->mem[peek16(d->dat, 0xc)], peek16(d->dat, 0x4)));
386
+		break;
387
+	case 0xe:
388
+		poke16(d->dat, 0x6, file_delete());
389
+		break;
386 390
 	}
387 391
 }
388 392